зеркало из https://github.com/mozilla/pjs.git
Merge m-c to s-c.
This commit is contained in:
Коммит
089dbf05e1
|
@ -174,8 +174,9 @@ NS_IMETHODIMP nsBMPEncoder::StartImageEncode(PRUint32 aWidth,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Returns the image buffer size
|
||||
NS_IMETHODIMP nsBMPEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
|
||||
// Returns the number of bytes in the image buffer used.
|
||||
// For a BMP file, this is all bytes in the buffer.
|
||||
NS_IMETHODIMP nsBMPEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOutputSize);
|
||||
*aOutputSize = mImageBufferSize;
|
||||
|
|
|
@ -111,9 +111,10 @@ NS_IMETHODIMP nsICOEncoder::InitFromData(const PRUint8* aData,
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Returns the image buffer size
|
||||
// Returns the number of bytes in the image buffer used
|
||||
// For an ICO file, this is all bytes in the buffer.
|
||||
NS_IMETHODIMP
|
||||
nsICOEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
|
||||
nsICOEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOutputSize);
|
||||
*aOutputSize = mImageBufferSize;
|
||||
|
@ -147,16 +148,16 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
|
|||
aStride, aInputFormat, noParams);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRUint32 imageBufferSize;
|
||||
mContainedEncoder->GetImageBufferSize(&imageBufferSize);
|
||||
PRUint32 PNGImageBufferSize;
|
||||
mContainedEncoder->GetImageBufferUsed(&PNGImageBufferSize);
|
||||
mImageBufferSize = ICONFILEHEADERSIZE + ICODIRENTRYSIZE +
|
||||
imageBufferSize;
|
||||
PNGImageBufferSize;
|
||||
mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
|
||||
if (!mImageBufferStart) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mImageBufferCurr = mImageBufferStart;
|
||||
mICODirEntry.mBytesInRes = imageBufferSize;
|
||||
mICODirEntry.mBytesInRes = PNGImageBufferSize;
|
||||
|
||||
EncodeFileHeader();
|
||||
EncodeInfoHeader();
|
||||
|
@ -164,8 +165,8 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
|
|||
char *imageBuffer;
|
||||
rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
memcpy(mImageBufferCurr, imageBuffer, imageBufferSize);
|
||||
mImageBufferCurr += imageBufferSize;
|
||||
memcpy(mImageBufferCurr, imageBuffer, PNGImageBufferSize);
|
||||
mImageBufferCurr += PNGImageBufferSize;
|
||||
} else {
|
||||
mContainedEncoder = new nsBMPEncoder();
|
||||
nsresult rv;
|
||||
|
@ -181,10 +182,10 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
|
|||
PRUint32 andMaskSize = ((GetRealWidth() + 31) / 32) * 4 * // row AND mask
|
||||
GetRealHeight(); // num rows
|
||||
|
||||
PRUint32 imageBufferSize;
|
||||
mContainedEncoder->GetImageBufferSize(&imageBufferSize);
|
||||
PRUint32 BMPImageBufferSize;
|
||||
mContainedEncoder->GetImageBufferUsed(&BMPImageBufferSize);
|
||||
mImageBufferSize = ICONFILEHEADERSIZE + ICODIRENTRYSIZE +
|
||||
imageBufferSize + andMaskSize;
|
||||
BMPImageBufferSize + andMaskSize;
|
||||
mImageBufferStart = static_cast<PRUint8*>(moz_malloc(mImageBufferSize));
|
||||
if (!mImageBufferStart) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -192,7 +193,7 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
|
|||
mImageBufferCurr = mImageBufferStart;
|
||||
|
||||
// The icon buffer does not include the BFH at all.
|
||||
mICODirEntry.mBytesInRes = imageBufferSize - BFH_LENGTH + andMaskSize;
|
||||
mICODirEntry.mBytesInRes = BMPImageBufferSize - BFH_LENGTH + andMaskSize;
|
||||
|
||||
// Encode the icon headers
|
||||
EncodeFileHeader();
|
||||
|
@ -202,13 +203,13 @@ nsICOEncoder::AddImageFrame(const PRUint8* aData,
|
|||
rv = mContainedEncoder->GetImageBuffer(&imageBuffer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
memcpy(mImageBufferCurr, imageBuffer + BFH_LENGTH,
|
||||
imageBufferSize - BFH_LENGTH);
|
||||
BMPImageBufferSize - BFH_LENGTH);
|
||||
// We need to fix the BMP height to be *2 for the AND mask
|
||||
PRUint32 fixedHeight = GetRealHeight() * 2;
|
||||
fixedHeight = NATIVE32_TO_LITTLE(fixedHeight);
|
||||
// The height is stored at an offset of 8 from the DIB header
|
||||
memcpy(mImageBufferCurr + 8, &fixedHeight, sizeof(fixedHeight));
|
||||
mImageBufferCurr += imageBufferSize - BFH_LENGTH;
|
||||
mImageBufferCurr += BMPImageBufferSize - BFH_LENGTH;
|
||||
|
||||
// Calculate rowsize in DWORD's
|
||||
PRUint32 rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
|
||||
|
|
|
@ -221,11 +221,11 @@ NS_IMETHODIMP nsJPEGEncoder::StartImageEncode(PRUint32 aWidth,
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Returns the image buffer size
|
||||
NS_IMETHODIMP nsJPEGEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
|
||||
// Returns the number of bytes in the image buffer used.
|
||||
NS_IMETHODIMP nsJPEGEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOutputSize);
|
||||
*aOutputSize = mImageBufferSize;
|
||||
*aOutputSize = mImageBufferUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -206,11 +206,11 @@ NS_IMETHODIMP nsPNGEncoder::StartImageEncode(PRUint32 aWidth,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Returns the image buffer size
|
||||
NS_IMETHODIMP nsPNGEncoder::GetImageBufferSize(PRUint32 *aOutputSize)
|
||||
// Returns the number of bytes in the image buffer used.
|
||||
NS_IMETHODIMP nsPNGEncoder::GetImageBufferUsed(PRUint32 *aOutputSize)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aOutputSize);
|
||||
*aOutputSize = mImageBufferSize;
|
||||
*aOutputSize = mImageBufferUsed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
/**
|
||||
* imgIEncoder interface
|
||||
*/
|
||||
[scriptable, uuid(d02e2d95-072d-4b91-8b8f-1300e45fcb2b)]
|
||||
[scriptable, uuid(4baa2d6e-fee7-42df-ae3f-5fbebc0c267c)]
|
||||
interface imgIEncoder : nsIAsyncInputStream
|
||||
{
|
||||
// Possible values for outputOptions. Multiple values are semicolon-separated.
|
||||
|
@ -159,8 +159,9 @@ interface imgIEncoder : nsIAsyncInputStream
|
|||
|
||||
/*
|
||||
* Sometimes an encoder can contain another encoder and direct access
|
||||
* to its buffer is necessary.
|
||||
* to its buffer is necessary. It is only safe to assume that the buffer
|
||||
* returned from getImageBuffer() is of size equal to getImageBufferUsed().
|
||||
*/
|
||||
[noscript] unsigned long getImageBufferSize();
|
||||
[noscript] unsigned long getImageBufferUsed();
|
||||
[noscript] charPtr getImageBuffer();
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
@ -102,8 +102,7 @@ js_InitArrayClass(JSContext *cx, JSObject *obj);
|
|||
extern bool
|
||||
js_InitContextBusyArrayTable(JSContext *cx);
|
||||
|
||||
namespace js
|
||||
{
|
||||
namespace js {
|
||||
|
||||
/* Create a dense array with no capacity allocated, length set to 0. */
|
||||
extern JSObject * JS_FASTCALL
|
||||
|
@ -136,7 +135,7 @@ NewDenseCopiedArray(JSContext *cx, uint32 length, const Value *vp, JSObject *pro
|
|||
extern JSObject *
|
||||
NewSlowEmptyArray(JSContext *cx);
|
||||
|
||||
}
|
||||
} /* namespace js */
|
||||
|
||||
extern JSBool
|
||||
js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp);
|
||||
|
@ -162,10 +161,7 @@ array_deleteElement(JSContext *cx, JSObject *obj, uint32 index, Value *rval, JSB
|
|||
extern bool
|
||||
GetElements(JSContext *cx, JSObject *aobj, jsuint length, js::Value *vp);
|
||||
|
||||
}
|
||||
|
||||
/* Natives exposed for optimization by the interpreter and JITs. */
|
||||
namespace js {
|
||||
|
||||
extern JSBool
|
||||
array_sort(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
@ -213,7 +209,4 @@ js_GetDenseArrayElementValue(JSContext *cx, JSObject *obj, jsid id,
|
|||
JSBool
|
||||
js_Array(JSContext *cx, uintN argc, js::Value *vp);
|
||||
|
||||
extern JSBool JS_FASTCALL
|
||||
js_EnsureDenseArrayCapacity(JSContext *cx, JSObject *obj, jsint i);
|
||||
|
||||
#endif /* jsarray_h___ */
|
||||
|
|
|
@ -697,15 +697,6 @@ CreateEvalCallObject(JSContext *cx, StackFrame *fp)
|
|||
|
||||
} // namespace js
|
||||
|
||||
JSObject * JS_FASTCALL
|
||||
js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain)
|
||||
{
|
||||
JS_ASSERT(!js_IsNamedLambda(fun));
|
||||
JS_ASSERT(scopeChain);
|
||||
JS_ASSERT(callee);
|
||||
return CallObject::create(cx, fun->script(), *scopeChain, callee);
|
||||
}
|
||||
|
||||
void
|
||||
js_PutCallObject(StackFrame *fp)
|
||||
{
|
||||
|
|
|
@ -312,9 +312,6 @@ js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs,
|
|||
uintN flags, JSObject *parent, JSAtom *atom,
|
||||
js::gc::AllocKind kind = JSFunction::FinalizeKind);
|
||||
|
||||
extern void
|
||||
js_FinalizeFunction(JSContext *cx, JSFunction *fun);
|
||||
|
||||
extern JSFunction * JS_FASTCALL
|
||||
js_CloneFunctionObject(JSContext *cx, JSFunction *fun, JSObject *parent, JSObject *proto,
|
||||
js::gc::AllocKind kind = JSFunction::FinalizeKind);
|
||||
|
@ -345,16 +342,9 @@ js_ValueToCallableObject(JSContext *cx, js::Value *vp, uintN flags);
|
|||
extern void
|
||||
js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, uintN flags);
|
||||
|
||||
extern JSObject * JS_FASTCALL
|
||||
js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain);
|
||||
|
||||
extern void
|
||||
js_PutCallObject(js::StackFrame *fp);
|
||||
|
||||
extern JSBool JS_FASTCALL
|
||||
js_PutCallObjectOnTrace(JSObject *scopeChain, uint32 nargs, js::Value *argv,
|
||||
uint32 nvars, js::Value *slots);
|
||||
|
||||
namespace js {
|
||||
|
||||
CallObject *
|
||||
|
|
|
@ -236,7 +236,11 @@ public class AboutHomeContent extends ScrollView {
|
|||
return is;
|
||||
File applicationPackage = new File(activity.getApplication().getPackageResourcePath());
|
||||
ZipFile zip = new ZipFile(applicationPackage);
|
||||
if (zip == null)
|
||||
return null;
|
||||
ZipEntry fileEntry = zip.getEntry("recommended-addons.json");
|
||||
if (fileEntry == null)
|
||||
return null;
|
||||
return zip.getInputStream(fileEntry);
|
||||
}
|
||||
|
||||
|
@ -246,6 +250,8 @@ public class AboutHomeContent extends ScrollView {
|
|||
try {
|
||||
byte[] buf = new byte[32768];
|
||||
InputStream fileStream = getRecommendedAddonsStream(activity);
|
||||
if (fileStream == null)
|
||||
return;
|
||||
StringBuffer jsonString = new StringBuffer();
|
||||
int read = 0;
|
||||
while ((read = fileStream.read(buf, 0, 32768)) != -1) {
|
||||
|
|
|
@ -234,7 +234,7 @@ public class AwesomeBar extends Activity implements GeckoEventListener {
|
|||
// If a space is found before any dot or colon, we assume this is a search query
|
||||
boolean spacedOut = space > -1 && (space < colon || space < dot);
|
||||
|
||||
return spacedOut || (dot == -1);
|
||||
return spacedOut || (dot == -1 && colon == -1);
|
||||
}
|
||||
|
||||
private void updateGoButton(String text) {
|
||||
|
|
|
@ -456,11 +456,13 @@ abstract public class GeckoApp
|
|||
MenuItem forward = aMenu.findItem(R.id.forward);
|
||||
MenuItem share = aMenu.findItem(R.id.share);
|
||||
MenuItem agentMode = aMenu.findItem(R.id.agent_mode);
|
||||
MenuItem saveAsPDF = aMenu.findItem(R.id.save_as_pdf);
|
||||
|
||||
if (tab == null) {
|
||||
bookmark.setEnabled(false);
|
||||
forward.setEnabled(false);
|
||||
share.setEnabled(false);
|
||||
saveAsPDF.setEnabled(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -481,7 +483,11 @@ abstract public class GeckoApp
|
|||
|
||||
// Don't share about:, chrome: and file: URIs
|
||||
String scheme = Uri.parse(tab.getURL()).getScheme();
|
||||
share.setEnabled(!scheme.equals("about") && !scheme.equals("chrome") && !scheme.equals("file"));
|
||||
share.setEnabled(!(scheme.equals("about") || scheme.equals("chrome") || scheme.equals("file")));
|
||||
|
||||
// Disable save as PDF for about:home and xul pages
|
||||
saveAsPDF.setEnabled(!(tab.getURL().equals("about:home") ||
|
||||
tab.getContentType().equals("application/vnd.mozilla.xul+xml")));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -667,7 +673,8 @@ abstract public class GeckoApp
|
|||
tab.setFaviconLoadId(id);
|
||||
}
|
||||
|
||||
void handleLocationChange(final int tabId, final String uri) {
|
||||
void handleLocationChange(final int tabId, final String uri,
|
||||
final String documentURI, final String contentType) {
|
||||
final Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
if (tab == null)
|
||||
return;
|
||||
|
@ -681,6 +688,8 @@ abstract public class GeckoApp
|
|||
|
||||
String oldBaseURI = tab.getURL();
|
||||
tab.updateURL(uri);
|
||||
tab.setDocumentURI(documentURI);
|
||||
tab.setContentType(contentType);
|
||||
|
||||
String baseURI = uri;
|
||||
if (baseURI.indexOf('#') != -1)
|
||||
|
@ -848,8 +857,10 @@ abstract public class GeckoApp
|
|||
} else if (event.equals("Content:LocationChange")) {
|
||||
final int tabId = message.getInt("tabID");
|
||||
final String uri = message.getString("uri");
|
||||
final String documentURI = message.getString("documentURI");
|
||||
final String contentType = message.getString("contentType");
|
||||
Log.i(LOGTAG, "URI - " + uri);
|
||||
handleLocationChange(tabId, uri);
|
||||
handleLocationChange(tabId, uri, documentURI, contentType);
|
||||
} else if (event.equals("Content:SecurityChange")) {
|
||||
final int tabId = message.getInt("tabID");
|
||||
final String mode = message.getString("mode");
|
||||
|
@ -902,7 +913,11 @@ abstract public class GeckoApp
|
|||
setLaunchState(GeckoApp.LaunchState.GeckoRunning);
|
||||
GeckoAppShell.sendPendingEventsToGecko();
|
||||
connectGeckoLayerClient();
|
||||
Looper.myQueue().addIdleHandler(new UpdateIdleHandler());
|
||||
GeckoAppShell.getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
Looper.myQueue().addIdleHandler(new UpdateIdleHandler());
|
||||
}
|
||||
});
|
||||
} else if (event.equals("ToggleChrome:Hide")) {
|
||||
mMainHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.lang.CharSequence;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.os.Build;
|
||||
|
@ -131,8 +132,12 @@ public class GeckoPreferences
|
|||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
String prefName = preference.getKey();
|
||||
setPreference(prefName, newValue);
|
||||
if (preference instanceof ListPreference)
|
||||
((ListPreference)preference).setSummary((String)newValue);
|
||||
if (preference instanceof ListPreference) {
|
||||
// We need to find the entry for the new value
|
||||
int newIndex = ((ListPreference)preference).findIndexOfValue((String) newValue);
|
||||
CharSequence newEntry = ((ListPreference)preference).getEntries()[newIndex];
|
||||
((ListPreference)preference).setSummary(newEntry);
|
||||
}
|
||||
if (preference instanceof LinkPreference)
|
||||
finish();
|
||||
return true;
|
||||
|
@ -177,6 +182,9 @@ public class GeckoPreferences
|
|||
GeckoAppShell.getMainHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
((ListPreference)pref).setValue(value);
|
||||
// Set the summary string to the current entry
|
||||
CharSequence selectedEntry = ((ListPreference)pref).getEntry();
|
||||
((ListPreference)pref).setSummary(selectedEntry);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -206,6 +206,7 @@ RES_LAYOUT_V11 = \
|
|||
|
||||
RES_VALUES = \
|
||||
res/values/defaults.xml \
|
||||
res/values/arrays.xml \
|
||||
res/values/colors.xml \
|
||||
res/values/styles.xml \
|
||||
res/values/themes.xml \
|
||||
|
@ -453,6 +454,7 @@ $(RES_VALUES): \
|
|||
$(srcdir)/resources/values/colors.xml \
|
||||
$(srcdir)/resources/values/styles.xml \
|
||||
$(srcdir)/resources/values/themes.xml \
|
||||
$(srcdir)/resources/values/arrays.xml \
|
||||
$(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/res/values/defaults.xml
|
||||
$(NSINSTALL) -D res/values
|
||||
$(NSINSTALL) $^ res/values
|
||||
|
|
|
@ -75,6 +75,8 @@ public class Tab {
|
|||
private HashMap<String, DoorHanger> mDoorHangers;
|
||||
private long mFaviconLoadId;
|
||||
private AgentMode mAgentMode = AgentMode.MOBILE;
|
||||
private String mDocumentURI;
|
||||
private String mContentType;
|
||||
|
||||
static class HistoryEntry {
|
||||
public final String mUri; // must never be null
|
||||
|
@ -103,6 +105,8 @@ public class Tab {
|
|||
mBookmark = false;
|
||||
mDoorHangers = new HashMap<String, DoorHanger>();
|
||||
mFaviconLoadId = 0;
|
||||
mDocumentURI = "";
|
||||
mContentType = "";
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
|
@ -182,6 +186,22 @@ public class Tab {
|
|||
}
|
||||
}
|
||||
|
||||
public void setDocumentURI(String documentURI) {
|
||||
mDocumentURI = documentURI;
|
||||
}
|
||||
|
||||
public String getDocumentURI() {
|
||||
return mDocumentURI;
|
||||
}
|
||||
|
||||
public void setContentType(String contentType) {
|
||||
mContentType = contentType;
|
||||
}
|
||||
|
||||
public String getContentType() {
|
||||
return mContentType;
|
||||
}
|
||||
|
||||
public void updateTitle(String title) {
|
||||
mTitle = (title == null ? "" : title);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.gfx.CairoImage;
|
||||
import org.mozilla.gecko.gfx.CairoUtils;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -46,6 +47,7 @@ import java.nio.ByteBuffer;
|
|||
public class BufferedCairoImage extends CairoImage {
|
||||
private ByteBuffer mBuffer;
|
||||
private int mWidth, mHeight, mFormat;
|
||||
private boolean mNeedToFreeBuffer = false;
|
||||
|
||||
/** Creates a buffered Cairo image from a byte buffer. */
|
||||
public BufferedCairoImage(ByteBuffer inBuffer, int inWidth, int inHeight, int inFormat) {
|
||||
|
@ -57,11 +59,23 @@ public class BufferedCairoImage extends CairoImage {
|
|||
mFormat = CairoUtils.bitmapConfigToCairoFormat(bitmap.getConfig());
|
||||
mWidth = bitmap.getWidth();
|
||||
mHeight = bitmap.getHeight();
|
||||
mBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 4);
|
||||
mNeedToFreeBuffer = true;
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * 4);
|
||||
bitmap.copyPixelsToBuffer(mBuffer.asIntBuffer());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (mNeedToFreeBuffer && mBuffer != null)
|
||||
GeckoAppShell.freeDirectBuffer(mBuffer);
|
||||
mNeedToFreeBuffer = false;
|
||||
mBuffer = null;
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ByteBuffer getBuffer() { return mBuffer; }
|
||||
@Override
|
||||
public int getWidth() { return mWidth; }
|
||||
|
|
|
@ -103,7 +103,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
|
||||
mScreenSize = new IntSize(1, 1);
|
||||
|
||||
mBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 2);
|
||||
mBuffer = GeckoAppShell.allocateDirectBuffer(mWidth * mHeight * 2);
|
||||
|
||||
mCairoImage = new CairoImage() {
|
||||
@Override
|
||||
|
@ -119,6 +119,17 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
mTileLayer = new SingleTileLayer(mCairoImage);
|
||||
}
|
||||
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (mBuffer != null)
|
||||
GeckoAppShell.freeDirectBuffer(mBuffer);
|
||||
mBuffer = null;
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
/** Attaches the root layer to the layer controller so that Gecko appears. */
|
||||
@Override
|
||||
public void setLayerController(LayerController layerController) {
|
||||
|
@ -151,28 +162,22 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
mGeckoViewport = new ViewportMetrics(viewportObject);
|
||||
mGeckoViewport.setSize(viewportSize);
|
||||
|
||||
mTileLayer.setOrigin(PointUtils.round(mGeckoViewport.getDisplayportOrigin()));
|
||||
mTileLayer.setResolution(mGeckoViewport.getZoomFactor());
|
||||
LayerController controller = getLayerController();
|
||||
synchronized (controller) {
|
||||
PointF displayportOrigin = mGeckoViewport.getDisplayportOrigin();
|
||||
mTileLayer.setOrigin(PointUtils.round(displayportOrigin));
|
||||
mTileLayer.setResolution(mGeckoViewport.getZoomFactor());
|
||||
|
||||
// Make sure LayerController metrics changes only happen in the
|
||||
// UI thread.
|
||||
final LayerController controller = getLayerController();
|
||||
|
||||
if (controller != null) {
|
||||
controller.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (onlyUpdatePageSize) {
|
||||
// Don't adjust page size when zooming unless zoom levels are
|
||||
// approximately equal.
|
||||
if (FloatUtils.fuzzyEquals(controller.getZoomFactor(), mGeckoViewport.getZoomFactor()))
|
||||
controller.setPageSize(mGeckoViewport.getPageSize());
|
||||
} else {
|
||||
controller.setViewportMetrics(mGeckoViewport);
|
||||
controller.notifyPanZoomControllerOfGeometryChange(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (onlyUpdatePageSize) {
|
||||
// Don't adjust page size when zooming unless zoom levels are
|
||||
// approximately equal.
|
||||
if (FloatUtils.fuzzyEquals(controller.getZoomFactor(),
|
||||
mGeckoViewport.getZoomFactor()))
|
||||
controller.setPageSize(mGeckoViewport.getPageSize());
|
||||
} else {
|
||||
controller.setViewportMetrics(mGeckoViewport);
|
||||
controller.notifyPanZoomControllerOfGeometryChange(true);
|
||||
}
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
Log.e(LOGTAG, "Bad viewport description: " + viewportDescription);
|
||||
|
@ -209,7 +214,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
b.copyPixelsFromBuffer(mBuffer.asIntBuffer());
|
||||
return b;
|
||||
} catch (OutOfMemoryError oom) {
|
||||
Log.e(LOGTAG, "Unable to create bitmap", oom);
|
||||
Log.w(LOGTAG, "Unable to create bitmap", oom);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,12 +58,13 @@ import android.view.GestureDetector;
|
|||
import android.view.ScaleGestureDetector;
|
||||
import android.view.View.OnTouchListener;
|
||||
import java.lang.Math;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The layer controller manages a tile that represents the visible page. It does panning and
|
||||
* zooming natively by delegating to a panning/zooming controller. Touch events can be dispatched
|
||||
* to a higher-level view.
|
||||
*
|
||||
* Many methods require that the monitor be held, with a synchronized (controller) { ... } block.
|
||||
*/
|
||||
public class LayerController {
|
||||
private static final String LOGTAG = "GeckoLayerController";
|
||||
|
@ -155,7 +156,8 @@ public class LayerController {
|
|||
}
|
||||
|
||||
/**
|
||||
* The view calls this to indicate that the viewport changed size.
|
||||
* The view calls this function to indicate that the viewport changed size. It must hold the
|
||||
* monitor while calling it.
|
||||
*
|
||||
* TODO: Refactor this to use an interface. Expose that interface only to the view and not
|
||||
* to the layer client. That way, the layer client won't be tempted to call this, which might
|
||||
|
@ -173,6 +175,7 @@ public class LayerController {
|
|||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Scrolls the viewport to the given point. You must hold the monitor while calling this. */
|
||||
public void scrollTo(PointF point) {
|
||||
mViewportMetrics.setOrigin(point);
|
||||
notifyLayerClientOfGeometryChange();
|
||||
|
@ -181,6 +184,7 @@ public class LayerController {
|
|||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Scrolls the viewport by the given offset. You must hold the monitor while calling this. */
|
||||
public void scrollBy(PointF point) {
|
||||
PointF origin = mViewportMetrics.getOrigin();
|
||||
origin.offset(point.x, point.y);
|
||||
|
@ -192,6 +196,7 @@ public class LayerController {
|
|||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Sets the current viewport. You must hold the monitor while calling this. */
|
||||
public void setViewport(RectF viewport) {
|
||||
mViewportMetrics.setViewport(viewport);
|
||||
notifyLayerClientOfGeometryChange();
|
||||
|
@ -200,6 +205,7 @@ public class LayerController {
|
|||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Sets the current page size. You must hold the monitor while calling this. */
|
||||
public void setPageSize(FloatSize size) {
|
||||
if (mViewportMetrics.getPageSize().fuzzyEquals(size))
|
||||
return;
|
||||
|
@ -215,7 +221,8 @@ public class LayerController {
|
|||
/**
|
||||
* Sets the entire viewport metrics at once. This function does not notify the layer client or
|
||||
* the pan/zoom controller, so you will need to call notifyLayerClientOfGeometryChange() or
|
||||
* notifyPanZoomControllerOfGeometryChange() after calling this.
|
||||
* notifyPanZoomControllerOfGeometryChange() after calling this. You must hold the monitor
|
||||
* while calling this.
|
||||
*/
|
||||
public void setViewportMetrics(ViewportMetrics viewport) {
|
||||
mViewportMetrics = new ViewportMetrics(viewport);
|
||||
|
@ -223,10 +230,15 @@ public class LayerController {
|
|||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Scales the viewport. You must hold the monitor while calling this. */
|
||||
public void scaleTo(float zoomFactor) {
|
||||
scaleWithFocus(zoomFactor, new PointF(0,0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Scales the viewport, keeping the given focus point in the same place before and after the
|
||||
* scale operation. You must hold the monitor while calling this.
|
||||
*/
|
||||
public void scaleWithFocus(float zoomFactor, PointF focus) {
|
||||
mViewportMetrics.scaleTo(zoomFactor, focus);
|
||||
|
||||
|
@ -237,6 +249,10 @@ public class LayerController {
|
|||
mView.requestRender();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the viewport origin and scales in one operation. You must hold the monitor while
|
||||
* calling this.
|
||||
*/
|
||||
public void scaleWithOrigin(float zoomFactor, PointF origin) {
|
||||
mViewportMetrics.setOrigin(origin);
|
||||
scaleTo(zoomFactor);
|
||||
|
|
|
@ -132,9 +132,6 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
|
||||
/**
|
||||
* Called whenever a new frame is about to be drawn.
|
||||
*
|
||||
* FIXME: This is racy. Layers and page sizes can be modified by the pan/zoom controller while
|
||||
* this is going on.
|
||||
*/
|
||||
public void onDrawFrame(GL10 gl) {
|
||||
long frameStartTime = SystemClock.uptimeMillis();
|
||||
|
@ -142,63 +139,68 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
|
|||
TextureReaper.get().reap(gl);
|
||||
|
||||
LayerController controller = mView.getController();
|
||||
Layer rootLayer = controller.getRoot();
|
||||
RenderContext screenContext = createScreenContext(), pageContext = createPageContext();
|
||||
RenderContext screenContext = createScreenContext();
|
||||
|
||||
if (!pageContext.fuzzyEquals(mLastPageContext)) {
|
||||
// the viewport or page changed, so show the scrollbars again
|
||||
// as per UX decision
|
||||
mVertScrollLayer.unfade();
|
||||
mHorizScrollLayer.unfade();
|
||||
mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY);
|
||||
} else if (mFadeRunnable.timeToFade()) {
|
||||
boolean stillFading = mVertScrollLayer.fade() | mHorizScrollLayer.fade();
|
||||
if (stillFading) {
|
||||
mFadeRunnable.scheduleNextFadeFrame();
|
||||
synchronized (controller) {
|
||||
Layer rootLayer = controller.getRoot();
|
||||
RenderContext pageContext = createPageContext();
|
||||
|
||||
if (!pageContext.fuzzyEquals(mLastPageContext)) {
|
||||
// the viewport or page changed, so show the scrollbars again
|
||||
// as per UX decision
|
||||
mVertScrollLayer.unfade();
|
||||
mHorizScrollLayer.unfade();
|
||||
mFadeRunnable.scheduleStartFade(ScrollbarLayer.FADE_DELAY);
|
||||
} else if (mFadeRunnable.timeToFade()) {
|
||||
boolean stillFading = mVertScrollLayer.fade() | mHorizScrollLayer.fade();
|
||||
if (stillFading) {
|
||||
mFadeRunnable.scheduleNextFadeFrame();
|
||||
}
|
||||
}
|
||||
mLastPageContext = pageContext;
|
||||
|
||||
/* Update layers. */
|
||||
if (rootLayer != null) rootLayer.update(gl);
|
||||
mShadowLayer.update(gl);
|
||||
mCheckerboardLayer.update(gl);
|
||||
mFrameRateLayer.update(gl);
|
||||
mVertScrollLayer.update(gl);
|
||||
mHorizScrollLayer.update(gl);
|
||||
|
||||
/* Draw the background. */
|
||||
gl.glClearColor(BACKGROUND_COLOR_R, BACKGROUND_COLOR_G, BACKGROUND_COLOR_B, 1.0f);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
/* Draw the drop shadow, if we need to. */
|
||||
Rect pageRect = getPageRect();
|
||||
RectF untransformedPageRect = new RectF(0.0f, 0.0f, pageRect.width(),
|
||||
pageRect.height());
|
||||
if (!untransformedPageRect.contains(controller.getViewport()))
|
||||
mShadowLayer.draw(pageContext);
|
||||
|
||||
/* Draw the checkerboard. */
|
||||
Rect scissorRect = transformToScissorRect(pageRect);
|
||||
gl.glEnable(GL10.GL_SCISSOR_TEST);
|
||||
gl.glScissor(scissorRect.left, scissorRect.top,
|
||||
scissorRect.width(), scissorRect.height());
|
||||
|
||||
mCheckerboardLayer.draw(screenContext);
|
||||
|
||||
/* Draw the layer the client added to us. */
|
||||
if (rootLayer != null)
|
||||
rootLayer.draw(pageContext);
|
||||
|
||||
gl.glDisable(GL10.GL_SCISSOR_TEST);
|
||||
|
||||
/* Draw the vertical scrollbar. */
|
||||
IntSize screenSize = new IntSize(controller.getViewportSize());
|
||||
if (pageRect.height() > screenSize.height)
|
||||
mVertScrollLayer.draw(pageContext);
|
||||
|
||||
/* Draw the horizontal scrollbar. */
|
||||
if (pageRect.width() > screenSize.width)
|
||||
mHorizScrollLayer.draw(pageContext);
|
||||
}
|
||||
mLastPageContext = pageContext;
|
||||
|
||||
/* Update layers. */
|
||||
if (rootLayer != null) rootLayer.update(gl);
|
||||
mShadowLayer.update(gl);
|
||||
mCheckerboardLayer.update(gl);
|
||||
mFrameRateLayer.update(gl);
|
||||
mVertScrollLayer.update(gl);
|
||||
mHorizScrollLayer.update(gl);
|
||||
|
||||
/* Draw the background. */
|
||||
gl.glClearColor(BACKGROUND_COLOR_R, BACKGROUND_COLOR_G, BACKGROUND_COLOR_B, 1.0f);
|
||||
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
/* Draw the drop shadow, if we need to. */
|
||||
Rect pageRect = getPageRect();
|
||||
RectF untransformedPageRect = new RectF(0.0f, 0.0f, pageRect.width(), pageRect.height());
|
||||
if (!untransformedPageRect.contains(controller.getViewport()))
|
||||
mShadowLayer.draw(pageContext);
|
||||
|
||||
/* Draw the checkerboard. */
|
||||
Rect scissorRect = transformToScissorRect(pageRect);
|
||||
gl.glEnable(GL10.GL_SCISSOR_TEST);
|
||||
gl.glScissor(scissorRect.left, scissorRect.top,
|
||||
scissorRect.width(), scissorRect.height());
|
||||
|
||||
mCheckerboardLayer.draw(screenContext);
|
||||
|
||||
/* Draw the layer the client added to us. */
|
||||
if (rootLayer != null)
|
||||
rootLayer.draw(pageContext);
|
||||
|
||||
gl.glDisable(GL10.GL_SCISSOR_TEST);
|
||||
|
||||
/* Draw the vertical scrollbar. */
|
||||
IntSize screenSize = new IntSize(controller.getViewportSize());
|
||||
if (pageRect.height() > screenSize.height)
|
||||
mVertScrollLayer.draw(pageContext);
|
||||
|
||||
/* Draw the horizontal scrollbar. */
|
||||
if (pageRect.width() > screenSize.width)
|
||||
mHorizScrollLayer.draw(pageContext);
|
||||
|
||||
/* Draw the FPS. */
|
||||
if (mShowFrameRate) {
|
||||
|
|
|
@ -51,6 +51,7 @@ import android.util.Log;
|
|||
import java.nio.ByteBuffer;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
import org.mozilla.gecko.FloatUtils;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
|
||||
/**
|
||||
* Draws a small rect. This is scaled to become a scrollbar.
|
||||
|
@ -74,6 +75,7 @@ public class ScrollbarLayer extends TileLayer {
|
|||
private final Bitmap mBitmap;
|
||||
private final Canvas mCanvas;
|
||||
private float mOpacity;
|
||||
private boolean mFinalized = false;
|
||||
|
||||
private ScrollbarLayer(CairoImage image, boolean vertical, ByteBuffer buffer) {
|
||||
super(false, image);
|
||||
|
@ -84,11 +86,22 @@ public class ScrollbarLayer extends TileLayer {
|
|||
mCanvas = new Canvas(mBitmap);
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (!mFinalized && mBuffer != null)
|
||||
GeckoAppShell.freeDirectBuffer(mBuffer);
|
||||
mFinalized = true;
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static ScrollbarLayer create(boolean vertical) {
|
||||
// just create an empty image for now, it will get drawn
|
||||
// on demand anyway
|
||||
int imageSize = nextPowerOfTwo(BAR_SIZE);
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(imageSize * imageSize * 4);
|
||||
ByteBuffer buffer = GeckoAppShell.allocateDirectBuffer(imageSize * imageSize * 4);
|
||||
CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize, CairoImage.FORMAT_ARGB32);
|
||||
return new ScrollbarLayer(image, vertical, buffer);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.gfx.BufferedCairoImage;
|
||||
import org.mozilla.gecko.gfx.CairoImage;
|
||||
import org.mozilla.gecko.gfx.IntSize;
|
||||
|
@ -56,6 +57,7 @@ import java.nio.IntBuffer;
|
|||
public class TextLayer extends SingleTileLayer {
|
||||
private final ByteBuffer mBuffer;
|
||||
private final IntSize mSize;
|
||||
private boolean mFinalized = false;
|
||||
|
||||
/*
|
||||
* This awkward pattern is necessary due to Java's restrictions on when one can call superclass
|
||||
|
@ -68,8 +70,18 @@ public class TextLayer extends SingleTileLayer {
|
|||
renderText(text);
|
||||
}
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
if (!mFinalized && mBuffer != null)
|
||||
GeckoAppShell.freeDirectBuffer(mBuffer);
|
||||
mFinalized = true;
|
||||
} finally {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
||||
public static TextLayer create(IntSize size, String text) {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(size.width * size.height * 4);
|
||||
ByteBuffer buffer = GeckoAppShell.allocateDirectBuffer(size.width * size.height * 4);
|
||||
BufferedCairoImage image = new BufferedCairoImage(buffer, size.width, size.height,
|
||||
CairoImage.FORMAT_ARGB32);
|
||||
return new TextLayer(buffer, image, size, text);
|
||||
|
|
|
@ -168,15 +168,5 @@ public abstract class TileLayer extends Layer {
|
|||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, repeatMode);
|
||||
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, repeatMode);
|
||||
}
|
||||
|
||||
protected static FloatBuffer createBuffer(float[] values) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(values.length * 4);
|
||||
byteBuffer.order(ByteOrder.nativeOrder());
|
||||
|
||||
FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
|
||||
floatBuffer.put(values);
|
||||
floatBuffer.position(0);
|
||||
return floatBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,10 @@
|
|||
<!ENTITY pref_clear_history_confirm "Browsing history will be deleted">
|
||||
<!ENTITY pref_clear_private_data "Clear private data">
|
||||
<!ENTITY pref_clear_private_data_confirm "Browsing settings, including passwords and cookies, will be deleted">
|
||||
<!ENTITY pref_enable_flash "Enable Flash">
|
||||
<!ENTITY pref_enable_flash_yes "Yes">
|
||||
<!ENTITY pref_enable_flash_tap_to_play "Tap To Play">
|
||||
<!ENTITY pref_enable_flash_no "No">
|
||||
|
||||
<!ENTITY quit "Quit">
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<string-array name="pref_enable_flash_entries">
|
||||
<item>@string/pref_enable_flash_yes</item>
|
||||
<item>@string/pref_enable_flash_tap_to_play</item>
|
||||
<item>@string/pref_enable_flash_no</item>
|
||||
</string-array>
|
||||
<string-array name="pref_enable_flash_values">
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>0</item>
|
||||
</string-array>
|
||||
</resources>
|
|
@ -19,6 +19,12 @@
|
|||
android:title="@string/pref_char_encoding"
|
||||
android:persistent="false" />
|
||||
|
||||
<ListPreference android:key="plugin.enable"
|
||||
android:title="@string/pref_enable_flash"
|
||||
android:entries="@array/pref_enable_flash_entries"
|
||||
android:entryValues="@array/pref_enable_flash_values"
|
||||
android:persistent="false" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/pref_category_privacy">
|
||||
|
|
|
@ -68,6 +68,10 @@
|
|||
<string name="pref_clear_history_confirm">&pref_clear_history_confirm;</string>
|
||||
<string name="pref_clear_private_data">&pref_clear_private_data;</string>
|
||||
<string name="pref_clear_private_data_confirm">&pref_clear_private_data_confirm;</string>
|
||||
<string name="pref_enable_flash">&pref_enable_flash;</string>
|
||||
<string name="pref_enable_flash_yes">&pref_enable_flash_yes;</string>
|
||||
<string name="pref_enable_flash_tap_to_play">&pref_enable_flash_tap_to_play;</string>
|
||||
<string name="pref_enable_flash_no">&pref_enable_flash_no;</string>
|
||||
|
||||
<string name="reload">&reload;</string>
|
||||
<string name="forward">&forward;</string>
|
||||
|
|
|
@ -560,7 +560,9 @@ public class PanZoomController
|
|||
GeckoAppShell.sendEventToGecko(e);
|
||||
mOverrideScrollAck = false;
|
||||
} else {
|
||||
mController.scrollBy(new PointF(mX.displacement, mY.displacement));
|
||||
synchronized (mController) {
|
||||
mController.scrollBy(new PointF(mX.displacement, mY.displacement));
|
||||
}
|
||||
}
|
||||
|
||||
mX.displacement = mY.displacement = 0;
|
||||
|
@ -592,18 +594,22 @@ public class PanZoomController
|
|||
|
||||
/* Performs one frame of a bounce animation. */
|
||||
private void advanceBounce() {
|
||||
float t = EASE_OUT_ANIMATION_FRAMES[mBounceFrame];
|
||||
ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
|
||||
mController.setViewportMetrics(newMetrics);
|
||||
mController.notifyLayerClientOfGeometryChange();
|
||||
mBounceFrame++;
|
||||
synchronized (mController) {
|
||||
float t = EASE_OUT_ANIMATION_FRAMES[mBounceFrame];
|
||||
ViewportMetrics newMetrics = mBounceStartMetrics.interpolate(mBounceEndMetrics, t);
|
||||
mController.setViewportMetrics(newMetrics);
|
||||
mController.notifyLayerClientOfGeometryChange();
|
||||
mBounceFrame++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Concludes a bounce animation and snaps the viewport into place. */
|
||||
private void finishBounce() {
|
||||
mController.setViewportMetrics(mBounceEndMetrics);
|
||||
mController.notifyLayerClientOfGeometryChange();
|
||||
mBounceFrame = -1;
|
||||
synchronized (mController) {
|
||||
mController.setViewportMetrics(mBounceEndMetrics);
|
||||
mController.notifyLayerClientOfGeometryChange();
|
||||
mBounceFrame = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -881,11 +887,14 @@ public class PanZoomController
|
|||
else
|
||||
spanRatio = 1.0f - (1.0f - spanRatio) * resistance;
|
||||
|
||||
float newZoomFactor = mController.getZoomFactor() * spanRatio;
|
||||
synchronized (mController) {
|
||||
float newZoomFactor = mController.getZoomFactor() * spanRatio;
|
||||
|
||||
mController.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(),
|
||||
mLastZoomFocus.y - detector.getFocusY()));
|
||||
mController.scaleWithFocus(newZoomFactor, new PointF(detector.getFocusX(), detector.getFocusY()));
|
||||
mController.scrollBy(new PointF(mLastZoomFocus.x - detector.getFocusX(),
|
||||
mLastZoomFocus.y - detector.getFocusY()));
|
||||
PointF focus = new PointF(detector.getFocusX(), detector.getFocusY());
|
||||
mController.scaleWithFocus(newZoomFactor, focus);
|
||||
}
|
||||
|
||||
mLastZoomFocus.set(detector.getFocusX(), detector.getFocusY());
|
||||
|
||||
|
|
|
@ -205,6 +205,7 @@ var BrowserApp = {
|
|||
IndexedDB.init();
|
||||
XPInstallObserver.init();
|
||||
ConsoleAPI.init();
|
||||
ClipboardHelper.init();
|
||||
|
||||
// Init LoginManager
|
||||
Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
|
||||
|
@ -435,6 +436,16 @@ var BrowserApp = {
|
|||
name: prefName
|
||||
};
|
||||
|
||||
// The plugin pref is actually two separate prefs, so
|
||||
// we need to handle it differently
|
||||
if (prefName == "plugin.enable") {
|
||||
// Use a string type for java's ListPreference
|
||||
pref.type = "string";
|
||||
pref.value = PluginHelper.getPluginPreference();
|
||||
prefs.push(pref);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (Services.prefs.getPrefType(prefName)) {
|
||||
case Ci.nsIPrefBranch.PREF_BOOL:
|
||||
|
@ -490,6 +501,13 @@ var BrowserApp = {
|
|||
setPreferences: function setPreferences(aPref) {
|
||||
let json = JSON.parse(aPref);
|
||||
|
||||
// The plugin pref is actually two separate prefs, so
|
||||
// we need to handle it differently
|
||||
if (json.name == "plugin.enable") {
|
||||
PluginHelper.setPluginPreference(json.value);
|
||||
return;
|
||||
}
|
||||
|
||||
// when sending to java, we normalized special preferences that use
|
||||
// integers and strings to represent booleans. here, we convert them back
|
||||
// to their actual types so we can store them.
|
||||
|
@ -753,12 +771,6 @@ var NativeWindow = {
|
|||
BrowserApp.addTab(url, { selected: false });
|
||||
});
|
||||
|
||||
this.add(Strings.browser.GetStringFromName("contextmenu.changeInputMethod"),
|
||||
this.textContext,
|
||||
function(aTarget) {
|
||||
Cc["@mozilla.org/imepicker;1"].getService(Ci.nsIIMEPicker).show();
|
||||
});
|
||||
|
||||
this.add(Strings.browser.GetStringFromName("contextmenu.fullScreen"),
|
||||
this.SelectorContext("video:not(:-moz-full-screen)"),
|
||||
function(aTarget) {
|
||||
|
@ -1381,12 +1393,16 @@ Tab.prototype = {
|
|||
|
||||
let browser = BrowserApp.getBrowserForWindow(contentWin);
|
||||
let uri = browser.currentURI.spec;
|
||||
let documentURI = browser.contentDocument.documentURIObject.spec;
|
||||
let contentType = browser.contentDocument.contentType;
|
||||
|
||||
let message = {
|
||||
gecko: {
|
||||
type: "Content:LocationChange",
|
||||
tabID: this.id,
|
||||
uri: uri
|
||||
uri: uri,
|
||||
documentURI: documentURI,
|
||||
contentType: contentType
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2898,6 +2914,83 @@ var ConsoleAPI = {
|
|||
}
|
||||
};
|
||||
|
||||
var ClipboardHelper = {
|
||||
init: function() {
|
||||
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.copy"), ClipboardHelper.getCopyContext(false), ClipboardHelper.copy.bind(ClipboardHelper));
|
||||
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.copyAll"), ClipboardHelper.getCopyContext(true), ClipboardHelper.copy.bind(ClipboardHelper));
|
||||
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.selectAll"), NativeWindow.contextmenus.textContext, ClipboardHelper.select.bind(ClipboardHelper));
|
||||
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.paste"), ClipboardHelper.pasteContext, ClipboardHelper.paste.bind(ClipboardHelper));
|
||||
NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.changeInputMethod"), NativeWindow.contextmenus.textContext, ClipboardHelper.inputMethod.bind(ClipboardHelper));
|
||||
},
|
||||
|
||||
get clipboardHelper() {
|
||||
delete this.clipboardHelper;
|
||||
return this.clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
|
||||
},
|
||||
|
||||
get clipboard() {
|
||||
delete this.clipboard;
|
||||
return this.clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
|
||||
},
|
||||
|
||||
copy: function(aElement) {
|
||||
let selectionStart = aElement.selectionStart;
|
||||
let selectionEnd = aElement.selectionEnd;
|
||||
if (selectionStart != selectionEnd) {
|
||||
string = aElement.value.slice(selectionStart, selectionEnd);
|
||||
this.clipboardHelper.copyString(string);
|
||||
} else {
|
||||
this.clipboardHelper.copyString(aElement.value);
|
||||
}
|
||||
},
|
||||
|
||||
select: function(aElement) {
|
||||
if (!aElement || !(aElement instanceof Ci.nsIDOMNSEditableElement))
|
||||
return;
|
||||
let target = aElement.QueryInterface(Ci.nsIDOMNSEditableElement);
|
||||
target.editor.selectAll();
|
||||
target.focus();
|
||||
},
|
||||
|
||||
paste: function(aElement) {
|
||||
if (!aElement || !(aElement instanceof Ci.nsIDOMNSEditableElement))
|
||||
return;
|
||||
let target = aElement.QueryInterface(Ci.nsIDOMNSEditableElement);
|
||||
target.editor.paste(Ci.nsIClipboard.kGlobalClipboard);
|
||||
target.focus();
|
||||
},
|
||||
|
||||
inputMethod: function(aElement) {
|
||||
Cc["@mozilla.org/imepicker;1"].getService(Ci.nsIIMEPicker).show();
|
||||
},
|
||||
|
||||
getCopyContext: function(isCopyAll) {
|
||||
return {
|
||||
matches: function(aElement) {
|
||||
if (NativeWindow.contextmenus.textContext.matches(aElement)) {
|
||||
let selectionStart = aElement.selectionStart;
|
||||
let selectionEnd = aElement.selectionEnd;
|
||||
if (selectionStart != selectionEnd)
|
||||
return true;
|
||||
else if (isCopyAll)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
pasteContext: {
|
||||
matches: function(aElement) {
|
||||
if (NativeWindow.contextmenus.textContext.matches(aElement)) {
|
||||
let flavors = ["text/unicode"];
|
||||
return ClipboardHelper.clipboard.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var PluginHelper = {
|
||||
showDoorHanger: function(aTab) {
|
||||
let message = Strings.browser.GetStringFromName("clickToPlayFlash.message");
|
||||
|
@ -2926,6 +3019,32 @@ var PluginHelper = {
|
|||
}
|
||||
},
|
||||
|
||||
getPluginPreference: function getPluginPreference() {
|
||||
let pluginDisable = Services.prefs.getBoolPref("plugin.disable");
|
||||
if (pluginDisable)
|
||||
return "0";
|
||||
|
||||
let clickToPlay = Services.prefs.getBoolPref("plugins.click_to_play");
|
||||
return clickToPlay ? "2" : "1";
|
||||
},
|
||||
|
||||
setPluginPreference: function setPluginPreference(aValue) {
|
||||
switch (aValue) {
|
||||
case "0": // Enable Plugins = No
|
||||
Services.prefs.setBoolPref("plugin.disable", true);
|
||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
||||
break;
|
||||
case "1": // Enable Plugins = Yes
|
||||
Services.prefs.clearUserPref("plugin.disable");
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", false);
|
||||
break;
|
||||
case "2": // Enable Plugins = Tap to Play (default)
|
||||
Services.prefs.clearUserPref("plugin.disable");
|
||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
// Mostly copied from /browser/base/content/browser.js
|
||||
addPluginClickCallback: function (plugin, callbackName /*callbackArgs...*/) {
|
||||
// XXX just doing (callback)(arg) was giving a same-origin error. bug?
|
||||
|
|
|
@ -11,18 +11,6 @@
|
|||
<!ENTITY newtab.label "New Tab">
|
||||
<!ENTITY closetab.label "Close Tab">
|
||||
|
||||
<!ENTITY cut.label "Cut">
|
||||
<!ENTITY copy.label "Copy">
|
||||
<!ENTITY copyAll.label "Copy All">
|
||||
<!ENTITY copylink.label "Copy Link Location">
|
||||
<!ENTITY paste.label "Paste">
|
||||
<!ENTITY pasteAndGo.label "Paste & Go">
|
||||
<!ENTITY delete.label "Delete">
|
||||
<!ENTITY selectAll.label "Select All">
|
||||
<!ENTITY noSuggestions.label "(No suggestions)">
|
||||
<!ENTITY addToDictionary.label "Add to Dictionary">
|
||||
<!ENTITY inputMethod.label "Select Input Method">
|
||||
|
||||
<!ENTITY allPagesHeader.label "All Pages">
|
||||
<!ENTITY bookmarksHeader.label "Bookmarks">
|
||||
<!ENTITY historyHeader.label "History">
|
||||
|
|
|
@ -256,6 +256,11 @@ contextmenu.openInNewTab=Open Link in New Tab
|
|||
contextmenu.changeInputMethod=Select Input Method
|
||||
contextmenu.fullScreen=Full Screen
|
||||
|
||||
contextmenu.copy=Copy
|
||||
contextmenu.copyAll=Copy All
|
||||
contextmenu.selectAll=Select All
|
||||
contextmenu.paste=Paste
|
||||
|
||||
# Select UI
|
||||
selectHelper.closeMultipleSelectDialog=Done
|
||||
|
||||
|
|
|
@ -359,8 +359,6 @@ FormHistory.prototype = {
|
|||
},
|
||||
|
||||
get dbConnection() {
|
||||
let connection;
|
||||
|
||||
// Make sure dbConnection can't be called from now to prevent infinite loops.
|
||||
delete FormHistory.prototype.dbConnection;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<xul:spacer flex="1"/>
|
||||
<xul:box class="icon"/>
|
||||
<html:div class="msg msgUnsupported">&missingPlugin;</html:div>
|
||||
<html:div class="msg msgClickToPlay"><html:a class="clickToPlayLink" href="">&clickToPlayPlugin;</html:a></html:div>
|
||||
<html:div class="msg msgClickToPlay">&clickToPlayPlugin;</html:div>
|
||||
<html:div class="msg msgDisabled">&disabledPlugin;</html:div>
|
||||
<html:div class="msg msgBlocked">&blockedPlugin.label;</html:div>
|
||||
<html:div class="msg msgCrashed"><!-- set at runtime --></html:div>
|
||||
|
|
|
@ -1049,11 +1049,11 @@ class nsRefPtr
|
|||
return get();
|
||||
}
|
||||
|
||||
nsCOMPtr_base::nsDerivedSafe<T>*
|
||||
T*
|
||||
operator->() const
|
||||
{
|
||||
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsRefPtr with operator->().");
|
||||
return reinterpret_cast<nsCOMPtr_base::nsDerivedSafe<T>*> (get());
|
||||
return get();
|
||||
}
|
||||
|
||||
// This operator is needed for gcc <= 4.0.* and for Sun Studio; it
|
||||
|
|
|
@ -429,45 +429,6 @@ nsCOMPtr_base
|
|||
{
|
||||
public:
|
||||
|
||||
template <class T>
|
||||
class
|
||||
NS_STACK_CLASS
|
||||
nsDerivedSafe : public T
|
||||
/*
|
||||
No client should ever see or have to type the name of this class. It is the
|
||||
artifact that makes it a compile-time error to call |AddRef| and |Release|
|
||||
on a |nsCOMPtr|. DO NOT USE THIS TYPE DIRECTLY IN YOUR CODE.
|
||||
|
||||
See |nsCOMPtr::operator->| and |nsRefPtr::operator->|.
|
||||
*/
|
||||
{
|
||||
private:
|
||||
NS_METHOD_(nsrefcnt) AddRef();
|
||||
NS_METHOD_(nsrefcnt) Release();
|
||||
//using T::AddRef;
|
||||
//using T::Release;
|
||||
/*
|
||||
We could use |using| above, except that gcc 4.2 on Mac has a bug
|
||||
which causes |using| be unable to make the function private in
|
||||
templated derived classes (see bug 689397).
|
||||
*/
|
||||
|
||||
~nsDerivedSafe(); // NOT TO BE IMPLEMENTED
|
||||
/*
|
||||
This dtor is added to make this class compatible with GCC 4.6.
|
||||
If the destructor for T is private, nsDerivedSafe's unimplemented destructor
|
||||
will be implicitly-declared by the compiler as deleted.
|
||||
Therefore this explicit dtor exists to avoid that deletion. See bug 689301.
|
||||
*/
|
||||
|
||||
protected:
|
||||
nsDerivedSafe(); // NOT TO BE IMPLEMENTED
|
||||
/*
|
||||
This ctor exists to avoid compile errors and warnings about nsDerivedSafe using the
|
||||
default ctor but inheriting classes without an empty ctor. See bug 209667.
|
||||
*/
|
||||
};
|
||||
|
||||
nsCOMPtr_base( nsISupports* rawPtr = 0 )
|
||||
: mRawPtr(rawPtr)
|
||||
{
|
||||
|
@ -840,11 +801,11 @@ class nsCOMPtr MOZ_FINAL
|
|||
return get();
|
||||
}
|
||||
|
||||
nsCOMPtr_base::nsDerivedSafe<T>*
|
||||
T*
|
||||
operator->() const
|
||||
{
|
||||
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
|
||||
return reinterpret_cast<nsCOMPtr_base::nsDerivedSafe<T>*> (get());
|
||||
return get();
|
||||
}
|
||||
|
||||
nsCOMPtr<T>*
|
||||
|
@ -1147,11 +1108,11 @@ class nsCOMPtr<nsISupports>
|
|||
return get();
|
||||
}
|
||||
|
||||
nsDerivedSafe<nsISupports>*
|
||||
nsISupports*
|
||||
operator->() const
|
||||
{
|
||||
NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL nsCOMPtr with operator->().");
|
||||
return reinterpret_cast<nsCOMPtr_base::nsDerivedSafe<nsISupports>*> (get());
|
||||
return get();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports>*
|
||||
|
|
Загрузка…
Ссылка в новой задаче