зеркало из https://github.com/mozilla/pjs.git
merge fx-team to m-c
This commit is contained in:
Коммит
2a38709bb1
|
@ -49,16 +49,15 @@ USE_STATIC_LIBS = 1
|
|||
endif
|
||||
|
||||
|
||||
CPPSRCS = nsBrowserProfileMigratorUtils.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH)_$(GNU_CXX),WINNT_)
|
||||
CPPSRCS += nsIEProfileMigrator.cpp \
|
||||
nsBrowserProfileMigratorUtils.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += nsSafariProfileMigrator.cpp \
|
||||
nsBrowserProfileMigratorUtils.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -98,7 +98,14 @@ def build_tar_package(tar, name, base, directory):
|
|||
|
||||
##############################################
|
||||
|
||||
source_dir = os.path.realpath('src')
|
||||
# The directories end up in the debug info, so the easy way of getting
|
||||
# a reproducible build is to run it in a know absolute directory.
|
||||
# We use a directory in /builds/slave because the mozilla infrastructure
|
||||
# cleans it up automatically.
|
||||
base_dir = "/builds/slave/moz-toolschain"
|
||||
|
||||
source_dir = base_dir + "/src"
|
||||
build_dir = base_dir + "/build"
|
||||
|
||||
def build_source_dir(prefix, version):
|
||||
return source_dir + '/' + prefix + version
|
||||
|
@ -133,8 +140,6 @@ mpfr_source_tar = download_uri(mpfr_source_uri)
|
|||
gmp_source_tar = download_uri(gmp_source_uri)
|
||||
gcc_source_tar = download_uri(gcc_source_uri)
|
||||
|
||||
build_dir = os.path.realpath('build')
|
||||
|
||||
binutils_source_dir = build_source_dir('binutils-', binutils_version)
|
||||
glibc_source_dir = build_source_dir('glibc-', glibc_version)
|
||||
tar_source_dir = build_source_dir('tar-', tar_version)
|
||||
|
@ -144,7 +149,7 @@ gmp_source_dir = build_source_dir('gmp-', gmp_version)
|
|||
gcc_source_dir = build_source_dir('gcc-', gcc_version)
|
||||
|
||||
if not os.path.exists(source_dir):
|
||||
os.mkdir(source_dir)
|
||||
os.makedirs(source_dir)
|
||||
extract(binutils_source_tar, source_dir)
|
||||
patch('binutils-deterministic.patch', 1, binutils_source_dir)
|
||||
extract(glibc_source_tar, source_dir)
|
||||
|
@ -160,7 +165,7 @@ if not os.path.exists(source_dir):
|
|||
|
||||
if os.path.exists(build_dir):
|
||||
shutil.rmtree(build_dir)
|
||||
os.mkdir(build_dir)
|
||||
os.makedirs(build_dir)
|
||||
|
||||
tar_inst_dir = build_dir + '/tar_inst'
|
||||
build_tar(build_dir, tar_inst_dir)
|
||||
|
|
|
@ -268,6 +268,11 @@ freetype/ftoutln.h
|
|||
freetype/ttnameid.h
|
||||
freetype/tttables.h
|
||||
freetype/t1tables.h
|
||||
freetype/ftlcdfil.h
|
||||
freetype/ftsizes.h
|
||||
freetype/ftadvanc.h
|
||||
freetype/ftbitmap.h
|
||||
freetype/ftxf86.h
|
||||
fribidi/fribidi.h
|
||||
FSp_fopen.h
|
||||
fstream
|
||||
|
|
|
@ -8056,7 +8056,7 @@ dnl ========================================================
|
|||
dnl Graphics checks.
|
||||
dnl ========================================================
|
||||
|
||||
if test "${OS_ARCH}" = "Darwin" -o "${MOZ_WIDGET_TOOLKIT}" = "android"; then
|
||||
if test "${OS_ARCH}" = "Darwin" -o "${MOZ_WIDGET_TOOLKIT}" = "android" -o "${MOZ_WIDGET_TOOLKIT}" = "gtk2"; then
|
||||
MOZ_ENABLE_SKIA=1
|
||||
else
|
||||
MOZ_ENABLE_SKIA=
|
||||
|
|
|
@ -2124,13 +2124,6 @@ public:
|
|||
DOUBLE_HI32_EXPMASK | DOUBLE_HI32_MANTMASK}}
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#define DOUBLE_COMPARE(LVAL, OP, RVAL) \
|
||||
(!DOUBLE_IS_NaN(LVAL) && !DOUBLE_IS_NaN(RVAL) && (LVAL) OP (RVAL))
|
||||
#else
|
||||
#define DOUBLE_COMPARE(LVAL, OP, RVAL) ((LVAL) OP (RVAL))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In the following helper macros we exploit the fact that the result of a
|
||||
* series of additions will not be finite if any one of the operands in the
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsEventStates.h"
|
||||
|
@ -774,9 +775,9 @@ nsImageLoadingContent::LoadImage(nsIURI* aNewURI,
|
|||
|
||||
nsLoadFlags loadFlags = aLoadFlags;
|
||||
PRInt32 corsmode = GetCORSMode();
|
||||
if (corsmode == nsImageLoadingContent::CORS_ANONYMOUS) {
|
||||
if (corsmode == nsGenericHTMLElement::CORS_ANONYMOUS) {
|
||||
loadFlags |= imgILoader::LOAD_CORS_ANONYMOUS;
|
||||
} else if (corsmode == nsImageLoadingContent::CORS_USE_CREDENTIALS) {
|
||||
} else if (corsmode == nsGenericHTMLElement::CORS_USE_CREDENTIALS) {
|
||||
loadFlags |= imgILoader::LOAD_CORS_USE_CREDENTIALS;
|
||||
}
|
||||
|
||||
|
@ -1186,8 +1187,8 @@ nsImageLoadingContent::CreateStaticImageClone(nsImageLoadingContent* aDest) cons
|
|||
aDest->mSuppressed = mSuppressed;
|
||||
}
|
||||
|
||||
nsImageLoadingContent::CORSMode
|
||||
nsGenericHTMLElement::CORSMode
|
||||
nsImageLoadingContent::GetCORSMode()
|
||||
{
|
||||
return CORS_NONE;
|
||||
return nsGenericHTMLElement::CORS_NONE;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsContentUtils.h" // NS_CONTENT_DELETE_LIST_MEMBER
|
||||
#include "nsString.h"
|
||||
#include "nsEventStates.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIDocument;
|
||||
|
@ -70,25 +71,6 @@ public:
|
|||
NS_DECL_IMGIDECODEROBSERVER
|
||||
NS_DECL_NSIIMAGELOADINGCONTENT
|
||||
|
||||
enum CORSMode {
|
||||
/**
|
||||
* The default of not using CORS to validate cross-origin loads.
|
||||
*/
|
||||
CORS_NONE,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, but do not send any credentials
|
||||
* (cookies, HTTP auth logins, etc) along with the request.
|
||||
*/
|
||||
CORS_ANONYMOUS,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, and send credentials such as cookies
|
||||
* and HTTP auth logins along with the request.
|
||||
*/
|
||||
CORS_USE_CREDENTIALS
|
||||
};
|
||||
|
||||
protected:
|
||||
/**
|
||||
* LoadImage is called by subclasses when the appropriate
|
||||
|
@ -201,7 +183,7 @@ protected:
|
|||
* Returns the CORS mode that will be used for all future image loads. The
|
||||
* default implementation returns CORS_NONE unconditionally.
|
||||
*/
|
||||
virtual CORSMode GetCORSMode();
|
||||
virtual nsGenericHTMLElement::CORSMode GetCORSMode();
|
||||
|
||||
private:
|
||||
/**
|
||||
|
|
|
@ -3950,7 +3950,7 @@ WebGLContext::DOMElementToImageSurface(nsIDOMElement *imageOrCanvas,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We disallow loading cross-domain images that have not been validated
|
||||
// We disallow loading cross-domain images and videos that have not been validated
|
||||
// with CORS as WebGL textures. The reason for doing that is that timing
|
||||
// attacks on WebGL shaders are able to retrieve approximations of the
|
||||
// pixel values in WebGL textures; see bug 655987.
|
||||
|
|
|
@ -995,7 +995,7 @@ NS_NewCanvasRenderingContext2DAzure(nsIDOMCanvasRenderingContext2D** aResult)
|
|||
!Preferences::GetBool("gfx.canvas.azure.prefer-skia", false)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
#elif !defined(XP_MACOSX) && !defined(ANDROID)
|
||||
#elif !defined(XP_MACOSX) && !defined(ANDROID) && !defined(XP_LINUX)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ _TEST_FILES = \
|
|||
image.png \
|
||||
test_canvas2d_crossorigin.html \
|
||||
test_webgl_crossorigin_textures.html \
|
||||
video.sjs \
|
||||
test_video_crossorigin.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=682299
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 682299</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="/tests/content/media/test/manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=682299">Mozilla Bug 682299</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 682299 **/
|
||||
|
||||
const MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
|
||||
const SECURITY_ERR = 0x805303e8;
|
||||
|
||||
function createCanvas(width, height) {
|
||||
var c = document.createElement("canvas");
|
||||
c.width = width;
|
||||
c.height = height;
|
||||
return c;
|
||||
}
|
||||
|
||||
function testCanvasDrawImage(v) {
|
||||
var c = createCanvas(v.width, v.height);
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.drawImage(v, 0, 0);
|
||||
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(true, "drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' worked");
|
||||
} catch(error) {
|
||||
ok(!v.crossorigin && error.result === SECURITY_ERR, "drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
|
||||
v.tainted = true;
|
||||
}
|
||||
}
|
||||
|
||||
function testCanvasCreatePattern(v) {
|
||||
var c = createCanvas(v.width, v.height);
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.fillStyle = ctx.createPattern(v, "");
|
||||
ctx.fillRect(0, 0, c.width, c.height);
|
||||
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(true, "createPattern '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' worked");
|
||||
} catch(error) {
|
||||
ok(!v.crossorigin && error.result === SECURITY_ERR, "createPattern '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
|
||||
v.tainted = true;
|
||||
}
|
||||
}
|
||||
|
||||
function testWebGL(v) {
|
||||
var tex = gl.createTexture();
|
||||
gl.bindTexture(gl.TEXTURE_2D, tex);
|
||||
|
||||
try {
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, v);
|
||||
ok(true, "createTexture from '" + v.src + "' with crossorigin='" + v.crossorigin + "' worked");
|
||||
} catch (error) {
|
||||
ok(!v.crossorigin && error.result === SECURITY_ERR, "createTexture from '" + v.src + "' with crossorigin='" + v.crossorigin + "' failed");
|
||||
v.tainted = true;
|
||||
}
|
||||
}
|
||||
|
||||
function testTaintedCanvas(v) {
|
||||
var c = createCanvas(v.width, v.height);
|
||||
var ctx = c.getContext("2d");
|
||||
ctx.drawImage(v, 0, 0);
|
||||
|
||||
try {
|
||||
var data = ctx.getImageData(0, 0, 1, 1);
|
||||
ok(false, "changing the CORS mode should not allow reading data from remote videos");
|
||||
} catch (error) {
|
||||
ok(error.result === SECURITY_ERR, "changing the CORS mode, drawImage '" + v.src + "' then getImageData with crossorigin='" + v.crossorigin + "' failed");
|
||||
}
|
||||
}
|
||||
|
||||
function vidDataSuccess(e) {
|
||||
ok(!e.target.error, "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
|
||||
|
||||
testCanvasDrawImage(e.target);
|
||||
testCanvasCreatePattern(e.target);
|
||||
if (gl) {
|
||||
testWebGL(e.target);
|
||||
}
|
||||
// If we change the CORS mode after loading the file without CORS it should still throw a security error
|
||||
if (e.target.tainted) {
|
||||
e.target.crossorigin = "anonymous";
|
||||
testTaintedCanvas(e.target);
|
||||
}
|
||||
|
||||
doneTest(e);
|
||||
}
|
||||
|
||||
function vidLoadFailure(e) {
|
||||
ok(false, "Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
|
||||
doneTest(e);
|
||||
}
|
||||
|
||||
function vidErrorSuccess(e) {
|
||||
ok(e.target.error.code === MEDIA_ERR_SRC_NOT_SUPPORTED,
|
||||
"Load '" + e.target.src + "' with crossorigin='" + e.target.crossorigin + "'");
|
||||
doneTest(e);
|
||||
}
|
||||
|
||||
function startTest(test, token) {
|
||||
var v = document.createElement('video');
|
||||
if (test.cors === "just-crossOrigin-without-value") {
|
||||
var div = document.createElement('div');
|
||||
div.innerHTML="<video crossorigin>";
|
||||
v = div.children[0];
|
||||
} else if (test.cors !== "missing-value-default") {
|
||||
v.crossorigin = test.cors;
|
||||
}
|
||||
v.token = token;
|
||||
manager.started(token);
|
||||
v.autoplay = true;
|
||||
v.preload = "auto";
|
||||
v.style.display = "none";
|
||||
if (test.nameIntent === test.corsIntent || test.corsIntent === "none" ||
|
||||
(test.nameIntent === "use-credentials" && test.corsIntent === "anonymous")) {
|
||||
v.addEventListener("loadeddata", vidDataSuccess, false);
|
||||
v.addEventListener("error", vidLoadFailure, false);
|
||||
} else {
|
||||
v.addEventListener("loadeddata", vidLoadFailure, false);
|
||||
v.addEventListener("error", vidErrorSuccess, false);
|
||||
}
|
||||
v.src = test.name;
|
||||
document.body.appendChild(v);
|
||||
}
|
||||
|
||||
function doneTest(e) {
|
||||
var v = e.target;
|
||||
v.parentNode.removeChild(v);
|
||||
manager.finished(v.token);
|
||||
}
|
||||
|
||||
var videoFile = getPlayableVideo(gSmallTests);
|
||||
if (!videoFile) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
videoFile = "?name=tests/content/media/test/" + videoFile.name + "&type=" + videoFile.type;
|
||||
|
||||
var gl;
|
||||
try {
|
||||
gl = createCanvas(16, 16).getContext("experimental-webgl");
|
||||
} catch (ex) {
|
||||
// Mac OS X 10.5 doesn't support WebGL, so we won't run the WebGL tests
|
||||
}
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
var corsTests = [];
|
||||
|
||||
const host = "http://example.com/tests/content/canvas/test/crossorigin/video.sjs";
|
||||
const serverAttrValues = [
|
||||
[ "&cors=none", "none" ],
|
||||
[ "&cors=anonymous", "anonymous" ],
|
||||
[ "&cors=use-credentials", "use-credentials" ]
|
||||
];
|
||||
const clientAttrValues = [
|
||||
[ "missing-value-default", "none" ],
|
||||
[ "", "anonymous" ],
|
||||
[ "just-crossOrigin-without-value", "anonymous" ],
|
||||
[ "anonymous", "anonymous" ],
|
||||
[ "use-credentials", "use-credentials" ],
|
||||
[ "foobar", "anonymous" ]
|
||||
];
|
||||
|
||||
// Build the video file test array
|
||||
for (var i = 0; i < serverAttrValues.length; i++) {
|
||||
for (var n = 0; n < clientAttrValues.length; n++) {
|
||||
corsTests.push({
|
||||
name: host + videoFile + serverAttrValues[i][0],
|
||||
nameIntent: serverAttrValues[i][1],
|
||||
cors: clientAttrValues[n][0],
|
||||
corsIntent: clientAttrValues[n][1]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
manager.runTests(corsTests, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,43 @@
|
|||
function parseQuery(request, key) {
|
||||
var params = request.queryString.split('&');
|
||||
for (var j = 0; j < params.length; ++j) {
|
||||
var p = params[j];
|
||||
if (p == key)
|
||||
return true;
|
||||
if (p.indexOf(key + "=") == 0)
|
||||
return p.substring(key.length + 1);
|
||||
if (p.indexOf("=") < 0 && key == "")
|
||||
return p;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleRequest(request, response) {
|
||||
var name = parseQuery(request, "name");
|
||||
var type = parseQuery(request, "type");
|
||||
var cors = parseQuery(request, "cors");
|
||||
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsILocalFile);
|
||||
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
|
||||
createInstance(Components.interfaces.nsIFileInputStream);
|
||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
var split = name.split("/");
|
||||
for(var i = 0; i < split.length; ++i) {
|
||||
file.append(split[i]);
|
||||
}
|
||||
fis.init(file, -1, -1, false);
|
||||
bis.setInputStream(fis);
|
||||
var bytes = bis.readBytes(bis.available());
|
||||
response.setHeader("Content-Length", ""+bytes.length, false);
|
||||
response.setHeader("Content-Type", type, false);
|
||||
if (cors == "anonymous") {
|
||||
response.setHeader("Access-Control-Allow-Origin", "*", false);
|
||||
} else if (cors == "use-credentials") {
|
||||
response.setHeader("Access-Control-Allow-Origin", "http://mochi.test:8888", false);
|
||||
response.setHeader("Access-Control-Allow-Credentials", "true", false);
|
||||
}
|
||||
response.write(bytes, bytes.length);
|
||||
bis.close();
|
||||
}
|
|
@ -73,6 +73,10 @@ public:
|
|||
CANPLAY_YES
|
||||
};
|
||||
|
||||
CORSMode GetCORSMode() {
|
||||
return mCORSMode;
|
||||
}
|
||||
|
||||
nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsHTMLMediaElement();
|
||||
|
||||
|
@ -233,8 +237,7 @@ public:
|
|||
// autoplay pref enabled, etc), it should start playing back.
|
||||
void NotifyAutoplayDataReady();
|
||||
|
||||
// Gets the pref media.enforce_same_site_origin, which determines
|
||||
// if we should check Access Controls, or allow cross domain loads.
|
||||
// Check if the media element had crossorigin set when loading started
|
||||
bool ShouldCheckAllowOrigin();
|
||||
|
||||
// Is the media element potentially playing as defined by the HTML 5 specification.
|
||||
|
@ -761,6 +764,9 @@ protected:
|
|||
|
||||
// True if a same-origin check has been done for the media element and resource.
|
||||
bool mMediaSecurityVerified;
|
||||
|
||||
// The CORS mode when loading the media element
|
||||
CORSMode mCORSMode;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2884,6 +2884,14 @@ nsGenericHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
const nsAttrValue::EnumTable nsGenericHTMLElement::kCORSAttributeTable[] = {
|
||||
// Order matters here
|
||||
// See ParseAttribute in nsHTMLImageElement or nsHTMLMediaElement
|
||||
{ "anonymous", nsGenericHTMLElement::CORS_ANONYMOUS },
|
||||
{ "use-credentials", nsGenericHTMLElement::CORS_USE_CREDENTIALS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* virtual */
|
||||
bool
|
||||
nsGenericHTMLFormElement::IsDisabled() const
|
||||
|
|
|
@ -542,6 +542,32 @@ public:
|
|||
return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared cross-origin resource sharing attributes so they don't get
|
||||
* duplicated on every CORS-enabled element
|
||||
*/
|
||||
|
||||
enum CORSMode {
|
||||
/**
|
||||
* The default of not using CORS to validate cross-origin loads.
|
||||
*/
|
||||
CORS_NONE,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, but do not send any credentials
|
||||
* (cookies, HTTP auth logins, etc) along with the request.
|
||||
*/
|
||||
CORS_ANONYMOUS,
|
||||
|
||||
/**
|
||||
* Validate cross-site loads using CORS, and send credentials such as cookies
|
||||
* and HTTP auth logins along with the request.
|
||||
*/
|
||||
CORS_USE_CREDENTIALS
|
||||
};
|
||||
|
||||
const static nsAttrValue::EnumTable kCORSAttributeTable[];
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Add/remove this element to the documents name cache
|
||||
|
|
|
@ -126,7 +126,7 @@ public:
|
|||
NS_DECL_NSIDOMHTMLIMAGEELEMENT
|
||||
|
||||
// override from nsImageLoadingContent
|
||||
nsImageLoadingContent::CORSMode GetCORSMode();
|
||||
CORSMode GetCORSMode();
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
|
||||
|
@ -245,13 +245,6 @@ NS_IMPL_URI_ATTR(nsHTMLImageElement, Src, src)
|
|||
NS_IMPL_STRING_ATTR(nsHTMLImageElement, UseMap, usemap)
|
||||
NS_IMPL_INT_ATTR(nsHTMLImageElement, Vspace, vspace)
|
||||
|
||||
static const nsAttrValue::EnumTable kCrossOriginTable[] = {
|
||||
// Order matters here; see ParseAttribute
|
||||
{ "anonymous", nsImageLoadingContent::CORS_ANONYMOUS },
|
||||
{ "use-credentials", nsImageLoadingContent::CORS_USE_CREDENTIALS },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
// crossorigin is not "limited to only known values" per spec, so it's
|
||||
// just a string attr purposes of the DOM crossOrigin property.
|
||||
NS_IMPL_STRING_ATTR(nsHTMLImageElement, CrossOrigin, crossorigin)
|
||||
|
@ -370,10 +363,10 @@ nsHTMLImageElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
return ParseAlignValue(aValue, aResult);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::crossorigin) {
|
||||
return aResult.ParseEnumValue(aValue, kCrossOriginTable, false,
|
||||
return aResult.ParseEnumValue(aValue, nsGenericHTMLElement::kCORSAttributeTable, false,
|
||||
// default value is anonymous if aValue is
|
||||
// not a value we understand
|
||||
&kCrossOriginTable[0]);
|
||||
&nsGenericHTMLElement::kCORSAttributeTable[0]);
|
||||
}
|
||||
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
|
||||
return true;
|
||||
|
@ -669,16 +662,16 @@ nsHTMLImageElement::CopyInnerTo(nsGenericElement* aDest) const
|
|||
return nsGenericHTMLElement::CopyInnerTo(aDest);
|
||||
}
|
||||
|
||||
nsImageLoadingContent::CORSMode
|
||||
nsGenericHTMLElement::CORSMode
|
||||
nsHTMLImageElement::GetCORSMode()
|
||||
{
|
||||
nsImageLoadingContent::CORSMode ret = nsImageLoadingContent::CORS_NONE;
|
||||
nsGenericHTMLElement::CORSMode ret = nsGenericHTMLElement::CORS_NONE;
|
||||
|
||||
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
|
||||
if (value) {
|
||||
NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
|
||||
"Why is this not an enum value?");
|
||||
ret = nsImageLoadingContent::CORSMode(value->GetEnumValue());
|
||||
ret = nsGenericHTMLElement::CORSMode(value->GetEnumValue());
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -940,6 +940,16 @@ nsresult nsHTMLMediaElement::LoadResource()
|
|||
mChannel = nsnull;
|
||||
}
|
||||
|
||||
// Set the media element's CORS mode only when loading a resource
|
||||
// By default, it's CORS_NONE
|
||||
mCORSMode = CORS_NONE;
|
||||
const nsAttrValue* value = GetParsedAttr(nsGkAtoms::crossorigin);
|
||||
if (value) {
|
||||
NS_ASSERTION(value->Type() == nsAttrValue::eEnum,
|
||||
"Why is this not an enum value?");
|
||||
mCORSMode = CORSMode(value->GetEnumValue());
|
||||
}
|
||||
|
||||
nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
|
||||
if (other) {
|
||||
// Clone it.
|
||||
|
@ -1002,7 +1012,7 @@ nsresult nsHTMLMediaElement::LoadResource()
|
|||
new nsCORSListenerProxy(loadListener,
|
||||
NodePrincipal(),
|
||||
channel,
|
||||
false,
|
||||
GetCORSMode() == CORS_USE_CREDENTIALS,
|
||||
&rv);
|
||||
} else {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
|
@ -1392,11 +1402,10 @@ nsHTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
|
|||
for (PRUint32 i = 0; i < entry->mElements.Length(); ++i) {
|
||||
nsHTMLMediaElement* elem = entry->mElements[i];
|
||||
bool equal;
|
||||
// Look for elements that have the same principal.
|
||||
// XXX when we implement crossorigin for video, we'll also need to check
|
||||
// for the same crossorigin mode here. Ditto for anything else that could
|
||||
// cause us to send different headers.
|
||||
if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal) {
|
||||
// Look for elements that have the same principal and CORS mode.
|
||||
// Ditto for anything else that could cause us to send different headers.
|
||||
if (NS_SUCCEEDED(elem->NodePrincipal()->Equals(NodePrincipal(), &equal)) && equal &&
|
||||
elem->mCORSMode == mCORSMode) {
|
||||
NS_ASSERTION(elem->mDecoder && elem->mDecoder->GetStream(), "Decoder gone");
|
||||
return elem;
|
||||
}
|
||||
|
@ -1438,7 +1447,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
|||
mHasSelfReference(false),
|
||||
mShuttingDown(false),
|
||||
mLoadIsSuspended(false),
|
||||
mMediaSecurityVerified(false)
|
||||
mMediaSecurityVerified(false),
|
||||
mCORSMode(CORS_NONE)
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
if (!gMediaElementLog) {
|
||||
|
@ -1559,6 +1569,8 @@ NS_IMETHODIMP nsHTMLMediaElement::Play()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMediaElement, Crossorigin, crossorigin)
|
||||
|
||||
bool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
|
@ -1577,6 +1589,12 @@ bool nsHTMLMediaElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
|
||||
return true;
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::crossorigin) {
|
||||
return aResult.ParseEnumValue(aValue, kCORSAttributeTable, false,
|
||||
// default value is anonymous if aValue is
|
||||
// not a value we understand
|
||||
&kCORSAttributeTable[0]);
|
||||
}
|
||||
if (aAttribute == nsGkAtoms::preload) {
|
||||
return aResult.ParseEnumValue(aValue, kPreloadTable, false);
|
||||
}
|
||||
|
@ -2330,7 +2348,7 @@ void nsHTMLMediaElement::DownloadStalled()
|
|||
|
||||
bool nsHTMLMediaElement::ShouldCheckAllowOrigin()
|
||||
{
|
||||
return Preferences::GetBool("media.enforce_same_site_origin", true);
|
||||
return mCORSMode != CORS_NONE;
|
||||
}
|
||||
|
||||
void nsHTMLMediaElement::UpdateReadyStateForData(NextFrameStatus aNextFrame)
|
||||
|
|
|
@ -76,7 +76,6 @@ var gTests = [
|
|||
var gTestNum = 0;
|
||||
var gVideo = null;
|
||||
var gTestedRemoved = false;
|
||||
var gOldPref;
|
||||
|
||||
function eventHandler(event) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
@ -93,6 +92,7 @@ function createVideo() {
|
|||
var v = document.createElement('video');
|
||||
v.addEventListener('loadeddata', eventHandler, false);
|
||||
v.addEventListener('error', eventHandler, false);
|
||||
v.crossorigin = 'anonymous';
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -102,15 +102,6 @@ function load() {
|
|||
"http://example.org/tests/content/media/test/file_access_controls.html",
|
||||
"We must be on a example.org:80");
|
||||
|
||||
// Ensure access control check pref is on.
|
||||
// media.enforce_same_site_origin
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
opener.ok(prefService!=null, "Get pref service");
|
||||
var branch = prefService.getBranch("media.");
|
||||
opener.ok(branch!=null, "Get media pref branch");
|
||||
gOldPref = branch.getBoolPref("enforce_same_site_origin");
|
||||
branch.setBoolPref("enforce_same_site_origin", true);
|
||||
nextTest();
|
||||
}
|
||||
|
||||
|
@ -159,11 +150,6 @@ function nextTest() {
|
|||
|
||||
function done() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
// Undo change to access control check pref.
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
var branch = prefService.getBranch("media.");
|
||||
branch.setBoolPref("enforce_same_site_origin", gOldPref);
|
||||
mediaTestCleanup();
|
||||
opener.done();
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
|
|||
rtype == txAExprResult::NUMBER) {
|
||||
double lval = aLeft->numberValue();
|
||||
double rval = aRight->numberValue();
|
||||
result = DOUBLE_COMPARE(lval, ==, rval);
|
||||
result = (lval == rval);
|
||||
}
|
||||
|
||||
// Otherwise compare as strings. Try to use the stringobject in
|
||||
|
@ -154,19 +154,19 @@ RelationalExpr::compareResults(txIEvalContext* aContext, txAExprResult* aLeft,
|
|||
switch (mOp) {
|
||||
case LESS_THAN:
|
||||
{
|
||||
return DOUBLE_COMPARE(leftDbl, <, rightDbl);
|
||||
return (leftDbl < rightDbl);
|
||||
}
|
||||
case LESS_OR_EQUAL:
|
||||
{
|
||||
return DOUBLE_COMPARE(leftDbl, <=, rightDbl);
|
||||
return (leftDbl <= rightDbl);
|
||||
}
|
||||
case GREATER_THAN:
|
||||
{
|
||||
return DOUBLE_COMPARE(leftDbl, >, rightDbl);
|
||||
return (leftDbl > rightDbl);
|
||||
}
|
||||
case GREATER_OR_EQUAL:
|
||||
{
|
||||
return DOUBLE_COMPARE(leftDbl, >=, rightDbl);
|
||||
return (leftDbl >= rightDbl);
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
* @status UNDER_DEVELOPMENT
|
||||
*/
|
||||
|
||||
[scriptable, uuid(c74b835f-bb68-4ab3-a02c-08152cbb09fa)]
|
||||
[scriptable, uuid(390c059a-0a26-4a44-96b6-3f8817bf92e9)]
|
||||
interface nsIDOMHTMLAudioElement : nsIDOMHTMLMediaElement
|
||||
{
|
||||
// Setup the audio stream for writing
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#endif
|
||||
%}
|
||||
|
||||
[scriptable, uuid(1f312b70-c1e1-40ca-94d4-5f70cac773da)]
|
||||
[scriptable, uuid(6733a409-fab3-45e1-af23-9af8c361bdfd)]
|
||||
interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
|
||||
{
|
||||
// error state
|
||||
|
@ -66,6 +66,7 @@ interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
|
|||
// network state
|
||||
attribute DOMString src;
|
||||
readonly attribute DOMString currentSrc;
|
||||
attribute DOMString crossorigin;
|
||||
const unsigned short NETWORK_EMPTY = 0;
|
||||
const unsigned short NETWORK_IDLE = 1;
|
||||
const unsigned short NETWORK_LOADING = 2;
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
* @status UNDER_DEVELOPMENT
|
||||
*/
|
||||
|
||||
[scriptable, uuid(8e6d81a9-a6e1-44af-95be-cbe86de36ede)]
|
||||
[scriptable, uuid(2274055b-8b3a-4a5a-8d72-5d5aea07021a)]
|
||||
interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
|
||||
{
|
||||
attribute long width;
|
||||
|
|
|
@ -214,6 +214,7 @@ ContainerRender(Container* aContainer,
|
|||
framebufferRect -= childOffset;
|
||||
aManager->CreateFBOWithTexture(framebufferRect,
|
||||
mode,
|
||||
aPreviousFrameBuffer,
|
||||
&frameBuffer,
|
||||
&containerSurface);
|
||||
childOffset.x = visibleRect.x;
|
||||
|
|
|
@ -1132,8 +1132,33 @@ LayerManagerOGL::SetLayerProgramProjectionMatrix(const gfx3DMatrix& aMatrix)
|
|||
} FOR_EACH_LAYER_PROGRAM_END
|
||||
}
|
||||
|
||||
static GLenum
|
||||
GetFrameBufferInternalFormat(GLContext* gl,
|
||||
GLuint aCurrentFrameBuffer,
|
||||
nsIWidget* aWidget)
|
||||
{
|
||||
if (aCurrentFrameBuffer == 0) { // default framebuffer
|
||||
return aWidget->GetGLFrameBufferFormat();
|
||||
}
|
||||
return LOCAL_GL_RGBA;
|
||||
}
|
||||
|
||||
static bool
|
||||
AreFormatsCompatibleForCopyTexImage2D(GLenum aF1, GLenum aF2)
|
||||
{
|
||||
// GL requires that the implementation has to handle copies between
|
||||
// different formats, so all are "compatible". GLES does not
|
||||
// require that.
|
||||
#ifdef USE_GLES2
|
||||
return (aF1 == aF2);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
|
||||
GLuint aCurrentFrameBuffer,
|
||||
GLuint *aFBO, GLuint *aTexture)
|
||||
{
|
||||
GLuint tex, fbo;
|
||||
|
@ -1142,12 +1167,40 @@ LayerManagerOGL::CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
|
|||
mGLContext->fGenTextures(1, &tex);
|
||||
mGLContext->fBindTexture(mFBOTextureTarget, tex);
|
||||
if (aInit == InitModeCopy) {
|
||||
mGLContext->fCopyTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
aRect.x, aRect.y,
|
||||
aRect.width, aRect.height,
|
||||
0);
|
||||
// We're going to create an RGBA temporary fbo. But to
|
||||
// CopyTexImage() from the current framebuffer, the framebuffer's
|
||||
// format has to be compatible with the new texture's. So we
|
||||
// check the format of the framebuffer here and take a slow path
|
||||
// if it's incompatible.
|
||||
GLenum format =
|
||||
GetFrameBufferInternalFormat(gl(), aCurrentFrameBuffer, mWidget);
|
||||
if (AreFormatsCompatibleForCopyTexImage2D(format, LOCAL_GL_RGBA)) {
|
||||
mGLContext->fCopyTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
aRect.x, aRect.y,
|
||||
aRect.width, aRect.height,
|
||||
0);
|
||||
} else {
|
||||
// Curses, incompatible formats. Take a slow path.
|
||||
//
|
||||
// XXX Technically CopyTexSubImage2D also has the requirement of
|
||||
// matching formats, but it doesn't seem to affect us in the
|
||||
// real world.
|
||||
mGLContext->fTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
aRect.width, aRect.height,
|
||||
0,
|
||||
LOCAL_GL_RGBA,
|
||||
LOCAL_GL_UNSIGNED_BYTE,
|
||||
NULL);
|
||||
mGLContext->fCopyTexSubImage2D(mFBOTextureTarget,
|
||||
0, // level
|
||||
0, 0, // offset
|
||||
aRect.x, aRect.y,
|
||||
aRect.width, aRect.height);
|
||||
}
|
||||
} else {
|
||||
mGLContext->fTexImage2D(mFBOTextureTarget,
|
||||
0,
|
||||
|
|
|
@ -308,6 +308,7 @@ public:
|
|||
* texture types.
|
||||
*/
|
||||
void CreateFBOWithTexture(const nsIntRect& aRect, InitMode aInit,
|
||||
GLuint aCurrentFrameBuffer,
|
||||
GLuint *aFBO, GLuint *aTexture);
|
||||
|
||||
GLuint QuadVBO() { return mQuadVBO; }
|
||||
|
|
|
@ -68,6 +68,7 @@ VPATH += \
|
|||
$(srcdir)/src/ports \
|
||||
$(srcdir)/src/opts \
|
||||
$(srcdir)/src/effects \
|
||||
$(srcdir)/src/utils \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_skia = \
|
||||
|
@ -317,6 +318,19 @@ DEFINES += -DSK_BUILD_FOR_ANDROID_NDK
|
|||
OS_CXXFLAGS += $(CAIRO_FT_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += \
|
||||
SkFontHost_FreeType.cpp \
|
||||
SkFontHost_linux.cpp \
|
||||
SkFontHost_gamma.cpp \
|
||||
SkTime_Unix.cpp \
|
||||
SkMMapStream.cpp \
|
||||
SkOSFile.cpp \
|
||||
$(NULL)
|
||||
|
||||
OS_CXXFLAGS += $(MOZ_PANGO_CFLAGS)
|
||||
endif
|
||||
|
||||
ifeq (windows,$(MOZ_WIDGET_TOOLKIT))
|
||||
EXPORTS_skia += \
|
||||
include/config/sk_stdint.h \
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
#include "gfxFT2Fonts.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
#include "cairo.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
@ -83,6 +85,9 @@
|
|||
#include FT_FREETYPE_H
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
|
||||
|
||||
#ifndef MOZ_PANGO
|
||||
|
@ -761,3 +766,23 @@ gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RefPtr<ScaledFont>
|
||||
gfxPlatformGtk::GetScaledFontForFont(gfxFont *aFont)
|
||||
{
|
||||
NativeFont nativeFont;
|
||||
nativeFont.mType = NATIVE_FONT_SKIA_FONT_FACE;
|
||||
nativeFont.mFont = aFont;
|
||||
RefPtr<ScaledFont> scaledFont =
|
||||
Factory::CreateScaledFontForNativeFont(nativeFont, aFont->GetAdjustedSize());
|
||||
|
||||
return scaledFont;
|
||||
}
|
||||
|
||||
bool
|
||||
gfxPlatformGtk::SupportsAzure(BackendType& aBackend)
|
||||
{
|
||||
aBackend = BACKEND_SKIA;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,11 @@ public:
|
|||
already_AddRefed<gfxASurface> CreateOffscreenSurface(const gfxIntSize& size,
|
||||
gfxASurface::gfxContentType contentType);
|
||||
|
||||
mozilla::RefPtr<mozilla::gfx::ScaledFont>
|
||||
GetScaledFontForFont(gfxFont *aFont);
|
||||
|
||||
virtual bool SupportsAzure(mozilla::gfx::BackendType& aBackend);
|
||||
|
||||
nsresult GetFontList(nsIAtom *aLangGroup,
|
||||
const nsACString& aGenericFamily,
|
||||
nsTArray<nsString>& aListOfFonts);
|
||||
|
|
|
@ -484,10 +484,8 @@ struct ParamTraits<mozilla::GraphicsFilterType>
|
|||
WriteParam(msg, int32(param));
|
||||
return;
|
||||
|
||||
default:
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
return;
|
||||
}
|
||||
NS_RUNTIMEABORT("not reached");
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "assembler/wtf/Platform.h"
|
||||
#include "assembler/assembler/MacroAssemblerCodeRef.h"
|
||||
#include "assembler/assembler/CodeLocation.h"
|
||||
#include "jsstdint.h"
|
||||
|
||||
#if ENABLE_ASSEMBLER
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <string.h>
|
||||
#include "assembler/jit/ExecutableAllocator.h"
|
||||
#include "assembler/wtf/Assertions.h"
|
||||
#include "jsstdint.h"
|
||||
|
||||
namespace JSC {
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#if ENABLE_ASSEMBLER && (WTF_CPU_X86 || WTF_CPU_X86_64)
|
||||
|
||||
#include "AssemblerBuffer.h"
|
||||
#include "jsstdint.h"
|
||||
#include "assembler/wtf/Assertions.h"
|
||||
#include "js/Vector.h"
|
||||
|
||||
|
|
|
@ -268,6 +268,11 @@ freetype/ftoutln.h
|
|||
freetype/ttnameid.h
|
||||
freetype/tttables.h
|
||||
freetype/t1tables.h
|
||||
freetype/ftlcdfil.h
|
||||
freetype/ftsizes.h
|
||||
freetype/ftadvanc.h
|
||||
freetype/ftbitmap.h
|
||||
freetype/ftxf86.h
|
||||
fribidi/fribidi.h
|
||||
FSp_fopen.h
|
||||
fstream
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
// |jit-test| error: InternalError
|
||||
version(0);
|
||||
eval("\
|
||||
function TimeFromYear( y ) {}\
|
||||
addTestCase( -2208988800000 );\
|
||||
function addTestCase( t ) {\
|
||||
var start = TimeFromYear((addTestCase(addTestCase << t, 0)));\
|
||||
new TestCase( \
|
||||
SECTION,\
|
||||
'(new Date('+d+')).getUTCDay()',\
|
||||
WeekDay((d)),\
|
||||
(new Date(let ({ stop } = 'properties.length' )('/ab[c\\\n]/'))).getUTCDay() \
|
||||
);\
|
||||
}\
|
||||
");
|
|
@ -0,0 +1,15 @@
|
|||
var n = 16;
|
||||
var a = new Int32Array(n);
|
||||
for (var i = 0; i < n; ++i) {
|
||||
a[i] = i;
|
||||
}
|
||||
var b = new Int32Array(n);
|
||||
for (var i = 0; i < n; ++i) {
|
||||
b[i] = i * 2;
|
||||
}
|
||||
|
||||
a.set(b, 0.99);
|
||||
|
||||
for (var i = 0; i < n; ++i) {
|
||||
assertEq(a[i], b[i]);
|
||||
}
|
|
@ -47,7 +47,6 @@
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsclist.h"
|
||||
#include "jsdhash.h"
|
||||
|
|
|
@ -103,7 +103,6 @@
|
|||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsprf.h"
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
* JS boolean implementation.
|
||||
*/
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsstdint.h"
|
||||
|
||||
#include "js/HashTable.h"
|
||||
#include "js/Vector.h"
|
||||
|
|
|
@ -54,8 +54,6 @@
|
|||
# include <string>
|
||||
#endif // ANDROID
|
||||
|
||||
#include "jsstdint.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsclist.h"
|
||||
|
|
|
@ -60,7 +60,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsprf.h"
|
||||
#include "prmjtime.h"
|
||||
#include "jsutil.h"
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <stdarg.h>
|
||||
#include "jsprvtd.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsclist.h"
|
||||
#include "jsapi.h"
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jsstdint.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
* Portable double to alphanumeric string and back converters.
|
||||
*/
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsdtoa.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include <string.h> /* for memset used when DEBUG */
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsclist.h"
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsgcchunk.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -824,7 +823,7 @@ js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *resu
|
|||
|
||||
if (lval.isDouble()) {
|
||||
double l = lval.toDouble(), r = rval.toDouble();
|
||||
*result = JSDOUBLE_COMPARE(l, ==, r, false);
|
||||
*result = (l == r);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -875,7 +874,7 @@ js::LooselyEqual(JSContext *cx, const Value &lval, const Value &rval, bool *resu
|
|||
double l, r;
|
||||
if (!ToNumber(cx, lvalue, &l) || !ToNumber(cx, rvalue, &r))
|
||||
return false;
|
||||
*result = JSDOUBLE_COMPARE(l, ==, r, false);
|
||||
*result = (l == r);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -887,7 +886,7 @@ js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equ
|
|||
if (lval.isString())
|
||||
return EqualStrings(cx, lval.toString(), rval.toString(), equal);
|
||||
if (lval.isDouble()) {
|
||||
*equal = JSDOUBLE_COMPARE(lval.toDouble(), ==, rval.toDouble(), JS_FALSE);
|
||||
*equal = (lval.toDouble() == rval.toDouble());
|
||||
return true;
|
||||
}
|
||||
if (lval.isObject()) {
|
||||
|
@ -905,13 +904,13 @@ js::StrictlyEqual(JSContext *cx, const Value &lref, const Value &rref, bool *equ
|
|||
if (lval.isDouble() && rval.isInt32()) {
|
||||
double ld = lval.toDouble();
|
||||
double rd = rval.toInt32();
|
||||
*equal = JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
|
||||
*equal = (ld == rd);
|
||||
return true;
|
||||
}
|
||||
if (lval.isInt32() && rval.isDouble()) {
|
||||
double ld = lval.toInt32();
|
||||
double rd = rval.toDouble();
|
||||
*equal = JSDOUBLE_COMPARE(ld, ==, rd, JS_FALSE);
|
||||
*equal = (ld == rd);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2325,7 +2324,7 @@ END_CASE(JSOP_CASE)
|
|||
double l, r; \
|
||||
if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r)) \
|
||||
goto error; \
|
||||
cond = JSDOUBLE_COMPARE(l, OP, r, false); \
|
||||
cond = (l OP r); \
|
||||
} \
|
||||
} \
|
||||
TRY_BRANCH_AFTER_COND(cond, 2); \
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
*/
|
||||
#include <stdlib.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "prmjtime.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "jsstdint.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
/*
|
||||
|
@ -129,15 +128,6 @@ JS_HASH_DOUBLE(jsdouble d)
|
|||
return u.s.lo ^ u.s.hi;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) \
|
||||
((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL)) \
|
||||
? (IFNAN) \
|
||||
: (LVAL) OP (RVAL))
|
||||
#else
|
||||
#define JSDOUBLE_COMPARE(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL))
|
||||
#endif
|
||||
|
||||
extern jsdouble js_NaN;
|
||||
extern jsdouble js_PositiveInfinity;
|
||||
extern jsdouble js_NegativeInfinity;
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsdhash.h"
|
||||
|
@ -72,7 +71,6 @@
|
|||
#include "jsproxy.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsscript.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsstr.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "json.h"
|
||||
|
|
|
@ -55,7 +55,6 @@
|
|||
#include "jsprf.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsxml.h"
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -856,8 +855,7 @@ Sprinter::put(const char *s, size_t len)
|
|||
s = stringAt(s - oldBase); /* this is where it lives now */
|
||||
memmove(bp, s, len);
|
||||
} else {
|
||||
JS_ASSERT(s < base || s >= base + size);
|
||||
memcpy(bp, s, len);
|
||||
js_memcpy(bp, s, len);
|
||||
}
|
||||
|
||||
bp[len] = 0;
|
||||
|
@ -2060,7 +2058,7 @@ DecompileDestructuringLHS(SprintStack *ss, jsbytecode *pc, jsbytecode *endpc, JS
|
|||
* the nb parameter.
|
||||
*/
|
||||
ptrdiff_t todo = ss->sprinter.getOffset();
|
||||
ss->sprinter.setOffset(todo + PAREN_SLOP);
|
||||
ss->sprinter.reserve(PAREN_SLOP);
|
||||
pc = Decompile(ss, pc, -((intN)ss->top));
|
||||
if (!pc)
|
||||
return NULL;
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "jsprf.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jspubtd.h"
|
||||
#include "jsstr.h"
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsclist.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsutil.h"
|
||||
|
|
|
@ -42,9 +42,9 @@
|
|||
/*
|
||||
* JS script operations.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jscrashreport.h"
|
||||
#include "jsprf.h"
|
||||
|
|
|
@ -54,7 +54,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsprf.h"
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jshash.h"
|
||||
#include "jsprf.h"
|
||||
|
@ -1544,7 +1543,7 @@ class TypedArrayTemplate
|
|||
int32_t length = -1;
|
||||
|
||||
if (argc > 1) {
|
||||
if (!NonstandardToInt32(cx, argv[1], &byteOffset))
|
||||
if (!ToInt32(cx, argv[1], &byteOffset))
|
||||
return NULL;
|
||||
if (byteOffset < 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
|
@ -1553,7 +1552,7 @@ class TypedArrayTemplate
|
|||
}
|
||||
|
||||
if (argc > 2) {
|
||||
if (!NonstandardToInt32(cx, argv[2], &length))
|
||||
if (!ToInt32(cx, argv[2], &length))
|
||||
return NULL;
|
||||
if (length < 0) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
|
@ -1625,7 +1624,7 @@ class TypedArrayTemplate
|
|||
int32_t off = 0;
|
||||
|
||||
if (args.length() > 1) {
|
||||
if (!NonstandardToInt32(cx, args[1], &off))
|
||||
if (!ToInt32(cx, args[1], &off))
|
||||
return false;
|
||||
|
||||
if (off < 0 || uint32_t(off) > getLength(tarray)) {
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
#ifdef WIN32
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsdhash.h"
|
||||
#include "jsprf.h"
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsprf.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsapi.h"
|
||||
|
@ -5315,7 +5314,7 @@ js_TestXMLEquality(JSContext *cx, const Value &v1, const Value &v2, JSBool *bp)
|
|||
if (ok) {
|
||||
d2 = JSVAL_IS_INT(v) ? JSVAL_TO_INT(v)
|
||||
: JSVAL_TO_DOUBLE(v);
|
||||
*bp = JSDOUBLE_COMPARE(d, ==, d2, JS_FALSE);
|
||||
*bp = (d == d2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -525,7 +525,7 @@ template void JS_FASTCALL stubs::DefFun<false>(VMFrame &f, JSFunction *fun);
|
|||
double l, r; \
|
||||
if (!ToNumber(cx, lval, &l) || !ToNumber(cx, rval, &r)) \
|
||||
THROWV(JS_FALSE); \
|
||||
cond = JSDOUBLE_COMPARE(l, OP, r, false); \
|
||||
cond = (l OP r); \
|
||||
} \
|
||||
regs.sp[-2].setBoolean(cond); \
|
||||
return cond; \
|
||||
|
@ -568,7 +568,7 @@ stubs::Not(VMFrame &f)
|
|||
f.regs.sp[-1].setBoolean(b);
|
||||
}
|
||||
|
||||
template <bool EQ, bool IFNAN>
|
||||
template <bool EQ>
|
||||
static inline bool
|
||||
StubEqualityOp(VMFrame &f)
|
||||
{
|
||||
|
@ -606,9 +606,9 @@ StubEqualityOp(VMFrame &f)
|
|||
double l = lval.toDouble();
|
||||
double r = rval.toDouble();
|
||||
if (EQ)
|
||||
cond = JSDOUBLE_COMPARE(l, ==, r, IFNAN);
|
||||
cond = (l == r);
|
||||
else
|
||||
cond = JSDOUBLE_COMPARE(l, !=, r, IFNAN);
|
||||
cond = (l != r);
|
||||
} else if (lval.isObject()) {
|
||||
JSObject *l = &lval.toObject(), *r = &rval.toObject();
|
||||
if (JSEqualityOp eq = l->getClass()->ext.equality) {
|
||||
|
@ -652,9 +652,9 @@ StubEqualityOp(VMFrame &f)
|
|||
return false;
|
||||
|
||||
if (EQ)
|
||||
cond = JSDOUBLE_COMPARE(l, ==, r, false);
|
||||
cond = (l == r);
|
||||
else
|
||||
cond = JSDOUBLE_COMPARE(l, !=, r, true);
|
||||
cond = (l != r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -666,7 +666,7 @@ StubEqualityOp(VMFrame &f)
|
|||
JSBool JS_FASTCALL
|
||||
stubs::Equal(VMFrame &f)
|
||||
{
|
||||
if (!StubEqualityOp<true, false>(f))
|
||||
if (!StubEqualityOp<true>(f))
|
||||
THROWV(JS_FALSE);
|
||||
return f.regs.sp[-2].toBoolean();
|
||||
}
|
||||
|
@ -674,7 +674,7 @@ stubs::Equal(VMFrame &f)
|
|||
JSBool JS_FASTCALL
|
||||
stubs::NotEqual(VMFrame &f)
|
||||
{
|
||||
if (!StubEqualityOp<false, true>(f))
|
||||
if (!StubEqualityOp<false>(f))
|
||||
THROWV(JS_FALSE);
|
||||
return f.regs.sp[-2].toBoolean();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "jsstdint.h"
|
||||
#include "jstypes.h"
|
||||
#include "jsutil.h"
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "mozilla/Util.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jsutil.h"
|
||||
#include "jsprf.h"
|
||||
#include "jswrapper.h"
|
||||
|
|
|
@ -49,7 +49,6 @@
|
|||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsstdint.h"
|
||||
#include "jslock.h"
|
||||
#include "jsworkers.h"
|
||||
|
||||
|
|
|
@ -30,8 +30,9 @@
|
|||
#ifndef PageBlock_h
|
||||
#define PageBlock_h
|
||||
|
||||
#include "mozilla/StdInt.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "jsstdint.h"
|
||||
#include "assembler/wtf/Platform.h"
|
||||
|
||||
namespace WTF {
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
#ifdef MOZ_MEDIA
|
||||
#include "nsHTMLVideoElement.h"
|
||||
#endif
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
|
@ -4151,6 +4152,7 @@ nsLayoutUtils::SurfaceFromElement(dom::Element* aElement,
|
|||
surf = imgSurf;
|
||||
}
|
||||
|
||||
result.mCORSUsed = video->GetCORSMode() != nsGenericHTMLElement::CORS_NONE;
|
||||
result.mSurface = surf;
|
||||
result.mSize = size;
|
||||
result.mPrincipal = principal.forget();
|
||||
|
|
|
@ -6582,10 +6582,10 @@ nsRuleNode::ComputeColumnData(void* aStartStruct,
|
|||
|
||||
// column-fill: enum
|
||||
SetDiscrete(*aRuleData->ValueForColumnFill(),
|
||||
column->mColumnFill, canStoreInRuleTree,
|
||||
SETDSC_ENUMERATED, parent->mColumnFill,
|
||||
NS_STYLE_COLUMN_FILL_BALANCE,
|
||||
0, 0, 0, 0);
|
||||
column->mColumnFill, canStoreInRuleTree,
|
||||
SETDSC_ENUMERATED, parent->mColumnFill,
|
||||
NS_STYLE_COLUMN_FILL_BALANCE,
|
||||
0, 0, 0, 0);
|
||||
|
||||
COMPUTE_END_RESET(Column, column)
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ LOCAL_INCLUDES = \
|
|||
-I$(srcdir)/../../../xul/base/src \
|
||||
-I$(srcdir)/../../../../content/svg/content/src \
|
||||
-I$(srcdir)/../../../../content/base/src \
|
||||
-I$(srcdir)/../../../../content/html/content/src \
|
||||
$(NULL)
|
||||
|
||||
libs::
|
||||
|
|
|
@ -61,6 +61,10 @@
|
|||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="org.mozilla.gecko.UPDATE"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
|
||||
<!-- Default browser intents -->
|
||||
<intent-filter>
|
||||
|
@ -112,6 +116,7 @@
|
|||
android:excludeFromRecents="true">
|
||||
<intent-filter>
|
||||
<action android:name="org.mozilla.gecko.restart"/>
|
||||
<action android:name="org.mozilla.gecko.restart_update"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@ abstract public class GeckoApp
|
|||
public static final String ACTION_DEBUG = "org.mozilla.gecko.DEBUG";
|
||||
public static final String ACTION_BOOKMARK = "org.mozilla.gecko.BOOKMARK";
|
||||
public static final String ACTION_LOAD = "org.mozilla.gecko.LOAD";
|
||||
public static final String ACTION_UPDATE = "org.mozilla.gecko.UPDATE";
|
||||
public static final String SAVED_STATE_URI = "uri";
|
||||
public static final String SAVED_STATE_TITLE = "title";
|
||||
public static final String SAVED_STATE_VIEWPORT = "viewport";
|
||||
|
@ -593,10 +594,9 @@ abstract public class GeckoApp
|
|||
}
|
||||
}
|
||||
|
||||
void getAndProcessThumbnailForTab(Tab tab) {
|
||||
Bitmap bitmap = null;
|
||||
if (Tabs.getInstance().isSelectedTab(tab))
|
||||
bitmap = mSoftwareLayerClient.getBitmap();
|
||||
void getAndProcessThumbnailForTab(final Tab tab) {
|
||||
final Bitmap bitmap = Tabs.getInstance().isSelectedTab(tab) ?
|
||||
mSoftwareLayerClient.getBitmap() : null;
|
||||
|
||||
if (bitmap != null) {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
@ -1052,6 +1052,8 @@ abstract public class GeckoApp
|
|||
}
|
||||
});
|
||||
}
|
||||
} else if (event.equals("Update:Restart")) {
|
||||
doRestart("org.mozilla.gecko.restart_update");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(LOGTAG, "Exception handling message \"" + event + "\":", e);
|
||||
|
@ -1458,6 +1460,11 @@ abstract public class GeckoApp
|
|||
}
|
||||
}
|
||||
|
||||
if (ACTION_UPDATE.equals(intent.getAction()) || args != null && args.contains("-alert update-app")) {
|
||||
Log.i(LOGTAG,"onCreate: Update request");
|
||||
checkAndLaunchUpdate();
|
||||
}
|
||||
|
||||
String uri = intent.getDataString();
|
||||
String title = uri;
|
||||
if (uri != null && uri.length() > 0) {
|
||||
|
@ -1606,6 +1613,7 @@ abstract public class GeckoApp
|
|||
GeckoAppShell.registerGeckoEventListener("Downloads:Done", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("CharEncoding:Data", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("CharEncoding:State", GeckoApp.mAppContext);
|
||||
GeckoAppShell.registerGeckoEventListener("Update:Restart", GeckoApp.mAppContext);
|
||||
|
||||
mConnectivityFilter = new IntentFilter();
|
||||
mConnectivityFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
|
@ -1641,10 +1649,6 @@ abstract public class GeckoApp
|
|||
return;
|
||||
}
|
||||
|
||||
// it would be good only to do this if MOZ_UPDATER was defined
|
||||
long startTime = SystemClock.uptimeMillis();
|
||||
checkAndLaunchUpdate();
|
||||
Log.w(LOGTAG, "checking for an update took " + (SystemClock.uptimeMillis() - startTime) + "ms");
|
||||
checkMigrateProfile();
|
||||
}
|
||||
}, 50);
|
||||
|
@ -2012,8 +2016,12 @@ abstract public class GeckoApp
|
|||
}
|
||||
|
||||
public void doRestart() {
|
||||
doRestart("org.mozilla.gecko.restart");
|
||||
}
|
||||
|
||||
public void doRestart(String action) {
|
||||
Log.i(LOGTAG, "doRestart(\"" + action + "\")");
|
||||
try {
|
||||
String action = "org.mozilla.gecko.restart";
|
||||
Intent intent = new Intent(action);
|
||||
intent.setClassName(getPackageName(),
|
||||
getPackageName() + ".Restarter");
|
||||
|
@ -2108,12 +2116,19 @@ abstract public class GeckoApp
|
|||
private void checkMigrateProfile() {
|
||||
File profileDir = getProfileDir();
|
||||
if (profileDir != null) {
|
||||
long currentTime = SystemClock.uptimeMillis();
|
||||
Log.i(LOGTAG, "checking profile migration in: " + profileDir.getAbsolutePath());
|
||||
final GeckoApp app = GeckoApp.mAppContext;
|
||||
final SetupScreen setupScreen = new SetupScreen(app);
|
||||
// don't show unless we take a while
|
||||
setupScreen.showDelayed(mMainHandler);
|
||||
GeckoAppShell.ensureSQLiteLibsLoaded(app.getApplication().getPackageResourcePath());
|
||||
ProfileMigrator profileMigrator =
|
||||
new ProfileMigrator(app.getContentResolver(), profileDir);
|
||||
profileMigrator.launchBackground();
|
||||
profileMigrator.launch();
|
||||
setupScreen.dismiss();
|
||||
long timeDiff = SystemClock.uptimeMillis() - currentTime;
|
||||
Log.i(LOGTAG, "Profile migration took " + timeDiff + " ms");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2363,7 +2378,7 @@ abstract public class GeckoApp
|
|||
while (tabsIter.hasNext()) {
|
||||
Tab tab = tabsIter.next();
|
||||
if (url.equals(tab.getURL())) {
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Select", String.valueOf(tab.getId())));
|
||||
Tabs.getInstance().selectTab(tab.getId());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -435,6 +435,7 @@ public class GeckoInputConnection
|
|||
|
||||
public void reset() {
|
||||
mComposing = false;
|
||||
mCompositionStart = -1;
|
||||
mBatchMode = false;
|
||||
mUpdateRequest = null;
|
||||
}
|
||||
|
@ -442,11 +443,17 @@ public class GeckoInputConnection
|
|||
// TextWatcher
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count)
|
||||
{
|
||||
if (mComposing && mCompositionStart != start) {
|
||||
// Changed range is different from the composition, need to reset the composition
|
||||
endComposition();
|
||||
}
|
||||
|
||||
if (!mComposing) {
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_COMPOSITION_BEGIN");
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_COMPOSITION_BEGIN, 0, 0));
|
||||
mComposing = true;
|
||||
mCompositionStart = start;
|
||||
|
||||
if (DEBUG) Log.d(LOGTAG, ". . . onTextChanged: IME_SET_SELECTION, start=" + start + ", len=" + before);
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
|
@ -474,6 +481,7 @@ public class GeckoInputConnection
|
|||
GeckoAppShell.sendEventToGecko(
|
||||
new GeckoEvent(GeckoEvent.IME_COMPOSITION_END, 0, 0));
|
||||
mComposing = false;
|
||||
mCompositionStart = -1;
|
||||
}
|
||||
|
||||
private void sendTextToGecko(CharSequence text, int caretPos) {
|
||||
|
@ -888,7 +896,8 @@ public class GeckoInputConnection
|
|||
}
|
||||
|
||||
// Is a composition active?
|
||||
boolean mComposing;
|
||||
private boolean mComposing;
|
||||
private int mCompositionStart = -1;
|
||||
|
||||
// IME stuff
|
||||
public static final int IME_STATE_DISABLED = 0;
|
||||
|
|
|
@ -68,6 +68,7 @@ FENNEC_JAVA_FILES = \
|
|||
AwesomeBarTabs.java \
|
||||
BrowserToolbar.java \
|
||||
ConfirmPreference.java \
|
||||
SyncPreference.java \
|
||||
db/AndroidBrowserDB.java \
|
||||
db/BrowserDB.java \
|
||||
db/LocalBrowserDB.java \
|
||||
|
@ -95,6 +96,7 @@ FENNEC_JAVA_FILES = \
|
|||
sqlite/ByteBufferInputStream.java \
|
||||
sqlite/SQLiteBridge.java \
|
||||
sqlite/SQLiteBridgeException.java \
|
||||
SetupScreen.java \
|
||||
SurfaceLockInfo.java \
|
||||
Tab.java \
|
||||
Tabs.java \
|
||||
|
@ -231,6 +233,7 @@ RES_LAYOUT = \
|
|||
res/layout/notification_progress.xml \
|
||||
res/layout/notification_progress_text.xml \
|
||||
res/layout/site_setting_title.xml \
|
||||
res/layout/setup_screen.xml \
|
||||
res/layout/tabs_row.xml \
|
||||
res/layout/tabs_tray.xml \
|
||||
res/layout/list_item_header.xml \
|
||||
|
@ -277,6 +280,7 @@ RES_DRAWABLE_NODPI = \
|
|||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_MDPI_V8 = \
|
||||
res/drawable-mdpi-v8/favicon.png \
|
||||
res/drawable-mdpi-v8/abouthome_icon.png \
|
||||
res/drawable-mdpi-v8/abouthome_logo.png \
|
||||
res/drawable-mdpi-v8/abouthome_separator.9.png \
|
||||
|
@ -319,6 +323,7 @@ RES_DRAWABLE_MDPI_V8 = \
|
|||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_HDPI_V8 = \
|
||||
res/drawable-hdpi-v8/favicon.png \
|
||||
res/drawable-hdpi-v8/home_bg.png \
|
||||
res/drawable-hdpi-v8/home_star.png \
|
||||
res/drawable-hdpi-v8/abouthome_icon.png \
|
||||
|
@ -383,6 +388,7 @@ RES_DRAWABLE_HDPI_V11 = \
|
|||
$(NULL)
|
||||
|
||||
RES_DRAWABLE_XHDPI_V11 = \
|
||||
res/drawable-xhdpi-v11/favicon.png \
|
||||
res/drawable-xhdpi-v11/abouthome_icon.png \
|
||||
res/drawable-xhdpi-v11/abouthome_logo.png \
|
||||
res/drawable-xhdpi-v11/abouthome_separator.9.png \
|
||||
|
@ -496,7 +502,6 @@ MOZ_ANDROID_DRAWABLES += \
|
|||
mobile/android/base/resources/drawable/awesomebar_tab_unselected.xml \
|
||||
mobile/android/base/resources/drawable/background.png \
|
||||
mobile/android/base/resources/drawable/desktop_notification.png \
|
||||
mobile/android/base/resources/drawable/favicon.png \
|
||||
mobile/android/base/resources/drawable/gecko_actionbar_bg.xml \
|
||||
mobile/android/base/resources/drawable/progress_spinner.xml \
|
||||
mobile/android/base/resources/drawable/progress_spinner_1.png \
|
||||
|
|
|
@ -69,12 +69,6 @@ public class ProfileMigrator {
|
|||
private File mProfileDir;
|
||||
private ContentResolver mCr;
|
||||
|
||||
/*
|
||||
Amount of Android history entries we will remember
|
||||
to prevent moving their last access date backwards.
|
||||
*/
|
||||
private static final int MAX_HISTORY_TO_CHECK = 1000;
|
||||
|
||||
/*
|
||||
These queries are derived from the low-level Places schema
|
||||
https://developer.mozilla.org/en/The_Places_database
|
||||
|
@ -88,41 +82,48 @@ public class ProfileMigrator {
|
|||
private final String bookmarkUrl = "a_url";
|
||||
private final String bookmarkTitle = "a_title";
|
||||
|
||||
/*
|
||||
The sort criterion here corresponds to the one used for the
|
||||
Awesomebar results. It's an simplification of Frecency.
|
||||
We must divide date by 1000 due to the micro (Places)
|
||||
vs milli (Android) distiction.
|
||||
*/
|
||||
private final String historyQuery =
|
||||
"SELECT places.url AS a_url, places.title AS a_title, "
|
||||
+ "history.visit_date AS a_date FROM "
|
||||
+ "(moz_historyvisits AS history JOIN moz_places AS places ON "
|
||||
+ "places.id = history.place_id) WHERE places.hidden <> 1 "
|
||||
+ "ORDER BY history.visit_date DESC";
|
||||
private final String historyUrl = "a_url";
|
||||
private final String historyTitle = "a_title";
|
||||
private final String historyDate = "a_date";
|
||||
|
||||
private final String faviconQuery =
|
||||
"SELECT places.url AS a_url, favicon.data AS a_data, "
|
||||
+ "favicon.mime_type AS a_mime FROM (moz_places AS places JOIN "
|
||||
+ "moz_favicons AS favicon ON places.favicon_id = favicon.id)";
|
||||
private final String faviconUrl = "a_url";
|
||||
private final String faviconData = "a_data";
|
||||
private final String faviconMime = "a_mime";
|
||||
"SELECT places.url AS a_url, places.title AS a_title,"
|
||||
+ "MAX(history.visit_date) AS a_date, COUNT(*) AS a_visits, "
|
||||
// see BrowserDB.filterAllSites for this formula
|
||||
+ "MAX(1, (((MAX(history.visit_date)/1000) - ?) / 86400000 + 120)) AS a_recent, "
|
||||
+ "favicon.data AS a_favicon_data, favicon.mime_type AS a_favicon_mime "
|
||||
+ "FROM (moz_historyvisits AS history JOIN moz_places AS places "
|
||||
+ "ON places.id = history.place_id "
|
||||
// Add favicon data if a favicon is present for this URL.
|
||||
+ "LEFT OUTER JOIN moz_favicons AS favicon "
|
||||
+ "ON places.favicon_id = favicon.id) "
|
||||
+ "WHERE places.hidden <> 1 "
|
||||
+ "GROUP BY a_url ORDER BY a_visits * a_recent DESC LIMIT ?";
|
||||
private final String historyUrl = "a_url";
|
||||
private final String historyTitle = "a_title";
|
||||
private final String historyDate = "a_date";
|
||||
private final String historyVisits = "a_visits";
|
||||
private final String faviconData = "a_favicon_data";
|
||||
private final String faviconMime = "a_favicon_mime";
|
||||
|
||||
public ProfileMigrator(ContentResolver cr, File profileDir) {
|
||||
mProfileDir = profileDir;
|
||||
mCr = cr;
|
||||
}
|
||||
|
||||
public void launchBackground() {
|
||||
// Work around http://code.google.com/p/android/issues/detail?id=11291
|
||||
// WebIconDatabase needs to be initialized within a looper thread.
|
||||
GeckoAppShell.getHandler().post(new PlacesTask());
|
||||
public void launch() {
|
||||
new PlacesTask().run();
|
||||
}
|
||||
|
||||
private class PlacesTask implements Runnable {
|
||||
// Get a list of the last times an URL was accessed
|
||||
protected Map<String, Long> gatherAndroidHistory() {
|
||||
protected Map<String, Long> gatherBrowserDBHistory() {
|
||||
Map<String, Long> history = new HashMap<String, Long>();
|
||||
|
||||
Cursor cursor = BrowserDB.getRecentHistory(mCr, MAX_HISTORY_TO_CHECK);
|
||||
Cursor cursor =
|
||||
BrowserDB.getRecentHistory(mCr, BrowserDB.getMaxHistoryCount());
|
||||
final int urlCol =
|
||||
cursor.getColumnIndexOrThrow(BrowserDB.URLColumns.URL);
|
||||
final int dateCol =
|
||||
|
@ -144,48 +145,71 @@ public class ProfileMigrator {
|
|||
return history;
|
||||
}
|
||||
|
||||
protected void addHistory(Map<String, Long> androidHistory,
|
||||
String url, String title, long date) {
|
||||
protected void addHistory(Map<String, Long> browserDBHistory,
|
||||
String url, String title, long date, int visits) {
|
||||
boolean allowUpdate = false;
|
||||
|
||||
if (!androidHistory.containsKey(url)) {
|
||||
// Android doesn't know the URL, allow it to be
|
||||
// inserted with places date
|
||||
if (!browserDBHistory.containsKey(url)) {
|
||||
// BrowserDB doesn't know the URL, allow it to be
|
||||
// inserted with places date.
|
||||
allowUpdate = true;
|
||||
} else {
|
||||
long androidDate = androidHistory.get(url);
|
||||
long androidDate = browserDBHistory.get(url);
|
||||
if (androidDate < date) {
|
||||
// Places URL hit is newer than Android,
|
||||
// allow it to be updated with places date
|
||||
// Places URL hit is newer than BrowserDB,
|
||||
// allow it to be updated with places date.
|
||||
allowUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowUpdate) {
|
||||
BrowserDB.updateVisitedHistory(mCr, url);
|
||||
BrowserDB.updateHistoryDate(mCr, url, date);
|
||||
if (title != null) {
|
||||
BrowserDB.updateHistoryTitle(mCr, url, title);
|
||||
}
|
||||
// The above records one visit. Subtract that one visit here.
|
||||
BrowserDB.updateHistoryEntry(mCr, url, title, date, visits - 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void migrateHistory(SQLiteBridge db) {
|
||||
Map<String, Long> androidHistory = gatherAndroidHistory();
|
||||
Map<String, Long> browserDBHistory = gatherBrowserDBHistory();
|
||||
final ArrayList<String> placesHistory = new ArrayList<String>();
|
||||
|
||||
try {
|
||||
ArrayList<Object[]> queryResult = db.query(historyQuery);
|
||||
final String[] queryParams = new String[] {
|
||||
/* current time */
|
||||
Long.toString(System.currentTimeMillis()),
|
||||
/*
|
||||
History entries to return. No point
|
||||
in retrieving more than we can store.
|
||||
*/
|
||||
Integer.toString(BrowserDB.getMaxHistoryCount())
|
||||
};
|
||||
ArrayList<Object[]> queryResult =
|
||||
db.query(historyQuery, queryParams);
|
||||
final int urlCol = db.getColumnIndex(historyUrl);
|
||||
final int titleCol = db.getColumnIndex(historyTitle);
|
||||
final int dateCol = db.getColumnIndex(historyDate);
|
||||
final int visitsCol = db.getColumnIndex(historyVisits);
|
||||
final int faviconMimeCol = db.getColumnIndex(faviconMime);
|
||||
final int faviconDataCol = db.getColumnIndex(faviconData);
|
||||
|
||||
for (Object[] resultRow: queryResult) {
|
||||
String url = (String)resultRow[urlCol];
|
||||
String title = (String)resultRow[titleCol];
|
||||
long date = Long.parseLong((String)(resultRow[dateCol])) / (long)1000;
|
||||
addHistory(androidHistory, url, title, date);
|
||||
int visits = Integer.parseInt((String)(resultRow[visitsCol]));
|
||||
addHistory(browserDBHistory, url, title, date, visits);
|
||||
placesHistory.add(url);
|
||||
|
||||
String mime = (String)resultRow[faviconMimeCol];
|
||||
if (mime != null) {
|
||||
// Some GIFs can cause us to lock up completely
|
||||
// without exceptions or anything. Not cool.
|
||||
if (mime.compareTo("image/gif") != 0) {
|
||||
ByteBuffer dataBuff =
|
||||
(ByteBuffer)resultRow[faviconDataCol];
|
||||
addFavicon(url, mime, dataBuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (SQLiteBridgeException e) {
|
||||
Log.i(LOGTAG, "Failed to get bookmarks: " + e.getMessage());
|
||||
|
@ -241,25 +265,6 @@ public class ProfileMigrator {
|
|||
}
|
||||
}
|
||||
|
||||
protected void migrateFavicons(SQLiteBridge db) {
|
||||
try {
|
||||
ArrayList<Object[]> queryResult = db.query(faviconQuery);
|
||||
final int urlCol = db.getColumnIndex(faviconUrl);
|
||||
final int mimeCol = db.getColumnIndex(faviconMime);
|
||||
final int dataCol = db.getColumnIndex(faviconData);
|
||||
|
||||
for (Object[] resultRow: queryResult) {
|
||||
String url = (String)resultRow[urlCol];
|
||||
String mime = (String)resultRow[mimeCol];
|
||||
ByteBuffer dataBuff = (ByteBuffer)resultRow[dataCol];
|
||||
addFavicon(url, mime, dataBuff);
|
||||
}
|
||||
} catch (SQLiteBridgeException e) {
|
||||
Log.i(LOGTAG, "Failed to get favicons: " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected void migratePlaces(File aFile) {
|
||||
String dbPath = aFile.getPath() + "/places.sqlite";
|
||||
String dbPathWal = aFile.getPath() + "/places.sqlite-wal";
|
||||
|
@ -279,7 +284,6 @@ public class ProfileMigrator {
|
|||
db = new SQLiteBridge(dbPath);
|
||||
migrateBookmarks(db);
|
||||
migrateHistory(db);
|
||||
migrateFavicons(db);
|
||||
db.close();
|
||||
|
||||
// Clean up
|
||||
|
|
|
@ -75,7 +75,9 @@ public class Restarter extends Activity {
|
|||
Log.i(LOGTAG, e.toString());
|
||||
}
|
||||
try {
|
||||
String action = "android.intent.action.MAIN";
|
||||
String action = "org.mozilla.gecko.restart_update".equals(getIntent().getAction()) ?
|
||||
App.ACTION_UPDATE : Intent.ACTION_MAIN;
|
||||
|
||||
Intent intent = new Intent(action);
|
||||
intent.setClassName("@ANDROID_PACKAGE_NAME@",
|
||||
"@ANDROID_PACKAGE_NAME@.App");
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Gian-Carlo Pascutto <gpascutto@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.AnimationDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
|
||||
public class SetupScreen extends Dialog
|
||||
{
|
||||
private static final String LOGTAG = "SetupScreen";
|
||||
// Default delay before showing dialog, in milliseconds
|
||||
private static final int DEFAULT_DELAY = 100;
|
||||
private AnimationDrawable mProgressSpinner;
|
||||
private Context mContext;
|
||||
private Timer mTimer;
|
||||
private TimerTask mShowTask;
|
||||
|
||||
public class ShowTask extends TimerTask {
|
||||
private Handler mHandler;
|
||||
|
||||
public ShowTask(Handler aHandler) {
|
||||
mHandler = aHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
SetupScreen.this.show();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
boolean stillInQueue = super.cancel();
|
||||
if (!stillInQueue) {
|
||||
mHandler.post(new Runnable() {
|
||||
public void run() {
|
||||
// SetupScreen.dismiss calls us,
|
||||
// we need to call the real Dialog.dismiss.
|
||||
SetupScreen.super.dismiss();
|
||||
}
|
||||
});
|
||||
}
|
||||
return stillInQueue;
|
||||
}
|
||||
}
|
||||
|
||||
public SetupScreen(Context aContext) {
|
||||
super(aContext, android.R.style.Theme_NoTitleBar_Fullscreen);
|
||||
mContext = aContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.setup_screen);
|
||||
setCancelable(false);
|
||||
|
||||
setTitle(R.string.splash_firstrun);
|
||||
|
||||
ImageView spinnerImage = (ImageView)findViewById(R.id.spinner_image);
|
||||
mProgressSpinner = (AnimationDrawable)spinnerImage.getBackground();
|
||||
spinnerImage.setImageDrawable(mProgressSpinner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged (boolean hasFocus) {
|
||||
mProgressSpinner.start();
|
||||
}
|
||||
|
||||
public void showDelayed(Handler aHandler) {
|
||||
showDelayed(aHandler, DEFAULT_DELAY);
|
||||
}
|
||||
|
||||
// Delay showing the dialog until at least aDelay ms have
|
||||
// passed. We need to know the handler to (eventually) post the UI
|
||||
// actions on.
|
||||
public void showDelayed(Handler aHandler, int aDelay) {
|
||||
mTimer = new Timer("SetupScreen");
|
||||
mShowTask = new ShowTask(aHandler);
|
||||
mTimer.schedule(mShowTask, aDelay);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
// Cancel the timers/tasks if we were using showDelayed,
|
||||
// and post to the correct handler.
|
||||
if (mShowTask != null) {
|
||||
mShowTask.cancel();
|
||||
mShowTask = null;
|
||||
} else {
|
||||
// If not using showDelayed, just dismiss here.
|
||||
super.dismiss();
|
||||
}
|
||||
if (mTimer != null) {
|
||||
mTimer.cancel();
|
||||
mTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Android code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009-2012
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Brian Nicholson <bnicholson@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.sync.setup.activities.SetupSyncActivity;
|
||||
|
||||
class SyncPreference extends Preference {
|
||||
private static final String FENNEC_ACCOUNT_TYPE = "org.mozilla.firefox_sync";
|
||||
private static final String SYNC_SETTINGS = "android.settings.SYNC_SETTINGS";
|
||||
|
||||
private Context mContext;
|
||||
|
||||
public SyncPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onClick() {
|
||||
// show sync setup if no accounts exist; otherwise, show account settings
|
||||
Account[] accounts = AccountManager.get(mContext).getAccountsByType(FENNEC_ACCOUNT_TYPE);
|
||||
Intent intent;
|
||||
if (accounts.length > 0)
|
||||
intent = new Intent(SYNC_SETTINGS);
|
||||
else
|
||||
intent = new Intent(mContext, SetupSyncActivity.class);
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
}
|
|
@ -55,11 +55,13 @@ import java.util.List;
|
|||
|
||||
public final class Tab {
|
||||
private static final String LOGTAG = "GeckoTab";
|
||||
private static final int kThumbnailWidth = 120;
|
||||
private static final int kThumbnailHeight = 80;
|
||||
private static final int kThumbnailWidth = 136;
|
||||
private static final int kThumbnailHeight = 77;
|
||||
|
||||
private static int sMinDim = 0;
|
||||
private static float sMinDim = 0;
|
||||
private static float sDensity = 1;
|
||||
private static int sMinScreenshotWidth = 0;
|
||||
private static int sMinScreenshotHeight = 0;
|
||||
private int mId;
|
||||
private String mUrl;
|
||||
private String mTitle;
|
||||
|
@ -145,24 +147,73 @@ public final class Tab {
|
|||
return mThumbnail;
|
||||
}
|
||||
|
||||
void initMetrics() {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
sMinDim = Math.min(metrics.widthPixels / kThumbnailWidth, metrics.heightPixels / kThumbnailHeight);
|
||||
sDensity = metrics.density;
|
||||
}
|
||||
|
||||
float getMinDim() {
|
||||
if (sMinDim == 0)
|
||||
initMetrics();
|
||||
return sMinDim;
|
||||
}
|
||||
|
||||
float getDensity() {
|
||||
if (sDensity == 0.0f)
|
||||
initMetrics();
|
||||
return sDensity;
|
||||
}
|
||||
|
||||
int getMinScreenshotWidth() {
|
||||
if (sMinScreenshotWidth != 0)
|
||||
return sMinScreenshotWidth;
|
||||
return sMinScreenshotWidth = (int)(getMinDim() * kThumbnailWidth);
|
||||
}
|
||||
|
||||
int getMinScreenshotHeight() {
|
||||
if (sMinScreenshotHeight != 0)
|
||||
return sMinScreenshotHeight;
|
||||
return sMinScreenshotHeight = (int)(getMinDim() * kThumbnailHeight);
|
||||
}
|
||||
|
||||
int getThumbnailWidth() {
|
||||
return (int)(kThumbnailWidth * getDensity());
|
||||
}
|
||||
|
||||
int getThumbnailHeight() {
|
||||
return (int)(kThumbnailHeight * getDensity());
|
||||
}
|
||||
|
||||
public void updateThumbnail(final Bitmap b) {
|
||||
final Tab tab = this;
|
||||
GeckoAppShell.getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
if (sMinDim == 0) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
sMinDim = Math.min(metrics.widthPixels / 3, metrics.heightPixels / 2);
|
||||
sDensity = metrics.density;
|
||||
}
|
||||
if (b != null) {
|
||||
try {
|
||||
Bitmap cropped = Bitmap.createBitmap(b, 0, 0, sMinDim * 3, sMinDim * 2);
|
||||
Bitmap bitmap = Bitmap.createScaledBitmap(cropped, (int) (kThumbnailWidth * sDensity), (int) (kThumbnailHeight * sDensity), false);
|
||||
saveThumbnailToDB(new BitmapDrawable(bitmap));
|
||||
b.recycle();
|
||||
Bitmap cropped = null;
|
||||
/* Crop to screen width if the bitmap is larger than the screen width or height. If smaller and the
|
||||
* the aspect ratio is correct, just use the bitmap as is. Otherwise, fit the smaller
|
||||
* smaller dimension, then crop the larger dimention.
|
||||
*/
|
||||
if (getMinScreenshotWidth() < b.getWidth() && getMinScreenshotHeight() < b.getHeight())
|
||||
cropped = Bitmap.createBitmap(b, 0, 0, getMinScreenshotWidth(), getMinScreenshotHeight());
|
||||
else if (b.getWidth() * getMinScreenshotHeight() == b.getHeight() * getMinScreenshotWidth())
|
||||
cropped = b;
|
||||
else if (b.getWidth() * getMinScreenshotHeight() < b.getHeight() * getMinScreenshotWidth())
|
||||
cropped = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
|
||||
b.getWidth() * getMinScreenshotHeight() / getMinScreenshotWidth());
|
||||
else
|
||||
cropped = Bitmap.createBitmap(b, 0, 0,
|
||||
b.getHeight() * getMinScreenshotWidth() / getMinScreenshotHeight(),
|
||||
b.getHeight());
|
||||
|
||||
bitmap = Bitmap.createBitmap(cropped, 0, 0, (int) (138 * sDensity), (int) (78 * sDensity));
|
||||
Bitmap bitmap = Bitmap.createScaledBitmap(cropped, getThumbnailWidth(), getThumbnailHeight(), false);
|
||||
saveThumbnailToDB(new BitmapDrawable(bitmap));
|
||||
|
||||
if (!cropped.equals(b))
|
||||
b.recycle();
|
||||
mThumbnail = new BitmapDrawable(bitmap);
|
||||
cropped.recycle();
|
||||
} catch (OutOfMemoryError oom) {
|
||||
|
|
|
@ -288,8 +288,12 @@ public class Tabs implements GeckoEventListener {
|
|||
}
|
||||
|
||||
public void refreshThumbnails() {
|
||||
Iterator<Tab> iterator = tabs.values().iterator();
|
||||
while (iterator.hasNext())
|
||||
GeckoApp.mAppContext.getAndProcessThumbnailForTab(iterator.next());
|
||||
GeckoAppShell.getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
Iterator<Tab> iterator = tabs.values().iterator();
|
||||
while (iterator.hasNext())
|
||||
GeckoApp.mAppContext.getAndProcessThumbnailForTab(iterator.next());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,8 +91,8 @@ public class TabsTray extends Activity implements GeckoApp.OnTabsChangedListener
|
|||
}
|
||||
});
|
||||
|
||||
Tabs.getInstance().refreshThumbnails();
|
||||
GeckoApp.registerOnTabsChangedListener(this);
|
||||
Tabs.getInstance().refreshThumbnails();
|
||||
onTabsChanged(null);
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,7 @@ public class TabsTray extends Activity implements GeckoApp.OnTabsChangedListener
|
|||
void finishActivity() {
|
||||
finish();
|
||||
overridePendingTransition(0, R.anim.shrink_fade_out);
|
||||
GeckoAppShell.sendEventToGecko(new GeckoEvent("Tab:Screenshot:Cancel",""));
|
||||
}
|
||||
|
||||
// Adapter to bind tabs into a list
|
||||
|
|
|
@ -118,9 +118,31 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
new String[] { uri });
|
||||
}
|
||||
|
||||
public void updateHistoryDate(ContentResolver cr, String uri, long date) {
|
||||
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
|
||||
long date, int visits) {
|
||||
int oldVisits = 0;
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = cr.query(Browser.BOOKMARKS_URI,
|
||||
new String[] { Browser.BookmarkColumns.VISITS },
|
||||
Browser.BookmarkColumns.URL + " = ?",
|
||||
new String[] { uri },
|
||||
null);
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
oldVisits = cursor.getInt(0);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(Browser.BookmarkColumns.DATE, date);
|
||||
values.put(Browser.BookmarkColumns.VISITS, oldVisits + visits);
|
||||
if (title != null) {
|
||||
values.put(Browser.BookmarkColumns.TITLE, title);
|
||||
}
|
||||
|
||||
cr.update(Browser.BOOKMARKS_URI,
|
||||
values,
|
||||
|
@ -145,7 +167,8 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
BookmarkColumns.URL,
|
||||
BookmarkColumns.TITLE,
|
||||
BookmarkColumns.FAVICON,
|
||||
BookmarkColumns.DATE },
|
||||
BookmarkColumns.DATE,
|
||||
BookmarkColumns.VISITS },
|
||||
// Bookmarks that have not been visited have a date value
|
||||
// of 0, so don't pick them up in the history view.
|
||||
Browser.BookmarkColumns.DATE + " > 0",
|
||||
|
@ -155,6 +178,11 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
return new AndroidDBCursor(c);
|
||||
}
|
||||
|
||||
public int getMaxHistoryCount() {
|
||||
// Valid for Android versions up to 4.0.
|
||||
return 250;
|
||||
}
|
||||
|
||||
public void clearHistory(ContentResolver cr) {
|
||||
Browser.clearHistory(cr);
|
||||
}
|
||||
|
@ -357,6 +385,8 @@ public class AndroidBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
columnName = URL_COLUMN_THUMBNAIL;
|
||||
} else if (columnName.equals(BrowserDB.URLColumns.DATE_LAST_VISITED)) {
|
||||
columnName = Browser.BookmarkColumns.DATE;
|
||||
} else if (columnName.equals(BrowserDB.URLColumns.VISITS)) {
|
||||
columnName = Browser.BookmarkColumns.VISITS;
|
||||
}
|
||||
|
||||
return columnName;
|
||||
|
|
|
@ -50,6 +50,7 @@ public class BrowserDB {
|
|||
public static String FAVICON = "favicon";
|
||||
public static String THUMBNAIL = "thumbnail";
|
||||
public static String DATE_LAST_VISITED = "date-last-visited";
|
||||
public static String VISITS = "visits";
|
||||
}
|
||||
|
||||
private static BrowserDBIface sDb;
|
||||
|
@ -63,12 +64,15 @@ public class BrowserDB {
|
|||
|
||||
public void updateHistoryTitle(ContentResolver cr, String uri, String title);
|
||||
|
||||
public void updateHistoryDate(ContentResolver cr, String uri, long date);
|
||||
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
|
||||
long date, int visits);
|
||||
|
||||
public Cursor getAllVisitedHistory(ContentResolver cr);
|
||||
|
||||
public Cursor getRecentHistory(ContentResolver cr, int limit);
|
||||
|
||||
public int getMaxHistoryCount();
|
||||
|
||||
public void clearHistory(ContentResolver cr);
|
||||
|
||||
public Cursor getAllBookmarks(ContentResolver cr);
|
||||
|
@ -107,8 +111,9 @@ public class BrowserDB {
|
|||
sDb.updateHistoryTitle(cr, uri, title);
|
||||
}
|
||||
|
||||
public static void updateHistoryDate(ContentResolver cr, String uri, long date) {
|
||||
sDb.updateHistoryDate(cr, uri, date);
|
||||
public static void updateHistoryEntry(ContentResolver cr, String uri, String title,
|
||||
long date, int visits) {
|
||||
sDb.updateHistoryEntry(cr, uri, title, date, visits);
|
||||
}
|
||||
|
||||
public static Cursor getAllVisitedHistory(ContentResolver cr) {
|
||||
|
@ -119,6 +124,10 @@ public class BrowserDB {
|
|||
return sDb.getRecentHistory(cr, limit);
|
||||
}
|
||||
|
||||
public static int getMaxHistoryCount() {
|
||||
return sDb.getMaxHistoryCount();
|
||||
}
|
||||
|
||||
public static void clearHistory(ContentResolver cr) {
|
||||
sDb.clearHistory(cr);
|
||||
}
|
||||
|
|
|
@ -200,9 +200,31 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
new String[] { uri });
|
||||
}
|
||||
|
||||
public void updateHistoryDate(ContentResolver cr, String uri, long date) {
|
||||
public void updateHistoryEntry(ContentResolver cr, String uri, String title,
|
||||
long date, int visits) {
|
||||
int oldVisits = 0;
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = cr.query(appendProfile(History.CONTENT_URI),
|
||||
new String[] { History.VISITS },
|
||||
History.URL + " = ?",
|
||||
new String[] { uri },
|
||||
null);
|
||||
|
||||
if (cursor.moveToFirst()) {
|
||||
oldVisits = cursor.getInt(0);
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(History.DATE_LAST_VISITED, date);
|
||||
values.put(History.VISITS, oldVisits + visits);
|
||||
if (title != null) {
|
||||
values.put(History.TITLE, title);
|
||||
}
|
||||
|
||||
cr.update(appendProfile(History.CONTENT_URI),
|
||||
values,
|
||||
|
@ -226,7 +248,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
History.URL,
|
||||
History.TITLE,
|
||||
History.FAVICON,
|
||||
History.DATE_LAST_VISITED },
|
||||
History.DATE_LAST_VISITED,
|
||||
History.VISITS },
|
||||
History.DATE_LAST_VISITED + " > 0",
|
||||
null,
|
||||
History.DATE_LAST_VISITED + " DESC");
|
||||
|
@ -234,6 +257,10 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
return new LocalDBCursor(c);
|
||||
}
|
||||
|
||||
public int getMaxHistoryCount() {
|
||||
return MAX_HISTORY_COUNT;
|
||||
}
|
||||
|
||||
public void clearHistory(ContentResolver cr) {
|
||||
cr.delete(appendProfile(History.CONTENT_URI), null, null);
|
||||
}
|
||||
|
@ -401,6 +428,8 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
|
|||
columnName = ImageColumns.THUMBNAIL;
|
||||
} else if (columnName.equals(BrowserDB.URLColumns.DATE_LAST_VISITED)) {
|
||||
columnName = History.DATE_LAST_VISITED;
|
||||
} else if (columnName.equals(BrowserDB.URLColumns.VISITS)) {
|
||||
columnName = History.VISITS;
|
||||
}
|
||||
|
||||
return columnName;
|
||||
|
|
|
@ -162,7 +162,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateAndDraw", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Viewport:UpdateLater", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Document:Shown", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Tab:Selected", this);
|
||||
GeckoAppShell.registerGeckoEventListener("Tab:Selected:Done", this);
|
||||
|
||||
sendResizeEventIfNecessary();
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ public class GeckoSoftwareLayerClient extends LayerClient implements GeckoEventL
|
|||
} else if ("Viewport:UpdateLater".equals(event)) {
|
||||
mUpdateViewportOnEndDraw = true;
|
||||
} else if (("Document:Shown".equals(event) ||
|
||||
"Tab:Selected".equals(event)) &&
|
||||
"Tab:Selected:Done".equals(event)) &&
|
||||
(mTileLayer instanceof MultiTileLayer)) {
|
||||
beginTransaction(mTileLayer);
|
||||
try {
|
||||
|
|
|
@ -189,10 +189,24 @@ public class LayerController {
|
|||
public void setViewportSize(FloatSize size) {
|
||||
// Resize the viewport, and modify its zoom factor so that the page retains proportionally
|
||||
// zoomed relative to the screen.
|
||||
float oldHeight = mViewportMetrics.getSize().height;
|
||||
float oldWidth = mViewportMetrics.getSize().width;
|
||||
float oldZoomFactor = mViewportMetrics.getZoomFactor();
|
||||
mViewportMetrics.setSize(size);
|
||||
|
||||
// if the viewport got larger (presumably because the vkb went away), and the page
|
||||
// is smaller than the new viewport size, increase the page size so that the panzoomcontroller
|
||||
// doesn't zoom in to make it fit (bug 718270). this page size change is in anticipation of
|
||||
// gecko increasing the page size to match the new viewport size, which will happen the next
|
||||
// time we get a draw update.
|
||||
if (size.width >= oldWidth && size.height >= oldHeight) {
|
||||
FloatSize pageSize = mViewportMetrics.getPageSize();
|
||||
if (pageSize.width < size.width || pageSize.height < size.height) {
|
||||
mViewportMetrics.setPageSize(new FloatSize(Math.max(pageSize.width, size.width),
|
||||
Math.max(pageSize.height, size.height)));
|
||||
}
|
||||
}
|
||||
|
||||
PointF newFocus = new PointF(size.width / 2.0f, size.height / 2.0f);
|
||||
float newZoomFactor = size.width * oldZoomFactor / oldWidth;
|
||||
mViewportMetrics.scaleTo(newZoomFactor, newFocus);
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
<!ENTITY pref_font_size_large "Large">
|
||||
<!ENTITY pref_font_size_xlarge "Extra Large">
|
||||
<!ENTITY pref_use_master_password "Use master password">
|
||||
<!ENTITY pref_sync "Sync">
|
||||
|
||||
<!ENTITY quit "Quit">
|
||||
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.8 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.6 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
mobile/android/base/resources/drawable/favicon.png
Двоичные данные
mobile/android/base/resources/drawable/favicon.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 268 B |
|
@ -8,15 +8,15 @@
|
|||
android:layout_height="fill_parent">
|
||||
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="138dip"
|
||||
android:layout_height="80dip"
|
||||
android:background="@drawable/abouthome_topsite_shadow"
|
||||
android:padding="1dip"
|
||||
android:paddingTop="2dip">
|
||||
android:paddingBottom="2dip">
|
||||
|
||||
<ImageView android:id="@+id/thumbnail"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="80dip"
|
||||
android:layout_width="136dip"
|
||||
android:layout_height="77dip"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
style="@style/Screen"
|
||||
android:background="@drawable/tabs_tray_bg_repeat"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center" >
|
||||
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_gravity="center" >
|
||||
|
||||
<ImageView android:id="@+id/image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:src="@drawable/logo" />
|
||||
|
||||
<LinearLayout android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal" >
|
||||
|
||||
<ImageView android:id="@+id/spinner_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="10dp"
|
||||
android:background="@drawable/progress_spinner" />
|
||||
|
||||
<TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:textSize="15dp"
|
||||
android:textColor="#FFFFFF"
|
||||
android:typeface="sans"
|
||||
android:text="@string/splash_firstrun" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче