Merge from mozilla-central
@ -1152,3 +1152,8 @@ pref("full-screen-api.enabled", true);
|
||||
// number of startup crashes that can occur before starting into safe mode automatically
|
||||
// (this pref has no effect if more than 6 hours have passed since the last crash)
|
||||
pref("toolkit.startup.max_resumed_crashes", 2);
|
||||
|
||||
// The maximum amount of decoded image data we'll willingly keep around (we
|
||||
// might keep around more than this, but we'll try to get down to this value).
|
||||
// (This is intentionally on the high side; see bug 746055.)
|
||||
pref("image.mem.max_decoded_image_kb", 256000);
|
||||
|
@ -54,6 +54,11 @@ function e(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function requestFullscreen(element) {
|
||||
element.focus();
|
||||
element.mozRequestFullScreen();
|
||||
}
|
||||
|
||||
function begin() {
|
||||
addListener("change", change1);
|
||||
e("fse").mozRequestFullScreen();
|
||||
@ -65,7 +70,7 @@ function change1() {
|
||||
is(document.mozFullScreenElement, e("fse"), "Body should be FSE");
|
||||
|
||||
// Request full-screen from element not descendent from current FSE.
|
||||
e("non-fse").mozRequestFullScreen();
|
||||
requestFullscreen(e("non-fse"));
|
||||
}
|
||||
|
||||
function error1() {
|
||||
@ -73,7 +78,7 @@ function error1() {
|
||||
addListener("change", change2);
|
||||
is(document.mozFullScreenElement, e("fse"), "FSE should not change");
|
||||
var iframe = e("subdoc");
|
||||
iframe.contentDocument.body.mozRequestFullScreen();
|
||||
requestFullscreen(iframe.contentDocument.body);
|
||||
}
|
||||
|
||||
function change2() {
|
||||
@ -96,14 +101,14 @@ function change4() {
|
||||
removeListener("change", change4);
|
||||
is(document.mozFullScreenElement, null, "Should have left full-screen entirely");
|
||||
addListener("change", change5);
|
||||
e("fse").mozRequestFullScreen();
|
||||
requestFullscreen(e("fse"));
|
||||
}
|
||||
|
||||
function change5() {
|
||||
removeListener("change", change5);
|
||||
addListener("change", change6);
|
||||
is(document.mozFullScreenElement, e("fse"), "FSE should be e('fse')");
|
||||
e("fse-inner").mozRequestFullScreen();
|
||||
requestFullscreen(e("fse-inner"));
|
||||
}
|
||||
|
||||
function change6() {
|
||||
|
@ -2317,26 +2317,3 @@ nsDOMWindowUtils::GetPlugins(JSContext* cx, jsval* aPlugins)
|
||||
*aPlugins = OBJECT_TO_JSVAL(jsPlugins);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight)
|
||||
{
|
||||
if (!IsUniversalXPConnectCapable()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
if (!(aWidth >= 0.0 && aHeight >= 0.0)) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (!presShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
presShell->SetScrollPositionClampingScrollPortSize(
|
||||
nsPresContext::CSSPixelsToAppUnits(aWidth),
|
||||
nsPresContext::CSSPixelsToAppUnits(aHeight));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ interface nsIDOMFile;
|
||||
interface nsIFile;
|
||||
interface nsIDOMTouch;
|
||||
|
||||
[scriptable, uuid(66a68858-df38-40e1-a792-fda04ebcc084)]
|
||||
[scriptable, uuid(c7f303a1-4f7b-4d38-a192-c3f0e25dadb1)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -1110,12 +1110,4 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
readonly attribute jsval plugins;
|
||||
|
||||
/**
|
||||
* Set the scrollport size for the purposes of clamping scroll positions for
|
||||
* the root scroll frame of this document to be (aWidth,aHeight) in CSS pixels.
|
||||
*
|
||||
* The caller of this method must have UniversalXPConnect privileges.
|
||||
*/
|
||||
void setScrollPositionClampingScrollPortSize(in float aWidth, in float aHeight);
|
||||
};
|
||||
|
336
gfx/layers/TiledLayerBuffer.h
Normal file
@ -0,0 +1,336 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_TILEDLAYERBUFFER_H
|
||||
#define GFX_TILEDLAYERBUFFER_H
|
||||
|
||||
#define TILEDLAYERBUFFER_TILE_SIZE 256
|
||||
|
||||
// Debug defines
|
||||
//#define FORCE_BASICTILEDTHEBESLAYER
|
||||
//#define GFX_TILEDLAYER_DEBUG_OVERLAY
|
||||
//#define GFX_TILEDLAYER_PREF_WARNINGS
|
||||
|
||||
#include "nsRect.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
// An abstract implementation of a tile buffer. This code covers the logic of
|
||||
// moving and reusing tiles and leaves the validation up to the implementor. To
|
||||
// avoid the overhead of virtual dispatch, we employ the curiously recurring
|
||||
// template pattern.
|
||||
//
|
||||
// This tile buffer stores a valid region, which defines the areas that have
|
||||
// up-to-date content. The contents of tiles within this region will be reused
|
||||
// from paint to paint. It also stores the region that was modified in the last
|
||||
// paint operation; this is useful when one tiled layer buffer shadows another
|
||||
// (as in an off-main-thread-compositing scenario), so that the shadow tiled
|
||||
// layer buffer can correctly reflect the updates of the master layer buffer.
|
||||
//
|
||||
// The associated Tile may be of any type as long as the derived class can
|
||||
// validate and return tiles of that type. Tiles will be frequently copied, so
|
||||
// the tile type should be a reference or some other type with an efficient
|
||||
// copy constructor.
|
||||
//
|
||||
// It is required that the derived class specify the base class as a friend. It
|
||||
// must also implement the following public method:
|
||||
//
|
||||
// Tile GetPlaceholderTile() const;
|
||||
//
|
||||
// Returns a temporary placeholder tile used as a marker. This placeholder tile
|
||||
// must never be returned by validateTile and must be == to every instance
|
||||
// of a placeholder tile.
|
||||
//
|
||||
// Additionally, it must implement the following protected methods:
|
||||
//
|
||||
// Tile ValidateTile(Tile aTile, const nsIntPoint& aTileOrigin,
|
||||
// const nsIntRegion& aDirtyRect);
|
||||
//
|
||||
// Validates the dirtyRect. The returned Tile will replace the tile.
|
||||
//
|
||||
// void ReleaseTile(Tile aTile);
|
||||
//
|
||||
// Destroys the given tile.
|
||||
//
|
||||
// void SwapTiles(Tile& aTileA, Tile& aTileB);
|
||||
//
|
||||
// Swaps two tiles.
|
||||
|
||||
template<typename Derived, typename Tile>
|
||||
class TiledLayerBuffer
|
||||
{
|
||||
public:
|
||||
TiledLayerBuffer()
|
||||
: mRetainedWidth(0)
|
||||
, mRetainedHeight(0)
|
||||
{}
|
||||
|
||||
~TiledLayerBuffer() {}
|
||||
|
||||
// Given a tile origin aligned to a multiple of GetTileLength(),
|
||||
// return the tile that describes that region.
|
||||
// NOTE: To get the valid area of that tile you must intersect
|
||||
// (aTileOrigin.x, aTileOrigin.y, GetTileLength(), GetTileLength())
|
||||
// and GetValidRegion() to get the area of the tile that is valid.
|
||||
Tile GetTile(const nsIntPoint& aTileOrigin) const;
|
||||
|
||||
// Given a tile x, y relative to the top left of the layer, this function
|
||||
// will return the tile for
|
||||
// (x*GetTileLength(), y*GetTileLength(), GetTileLength(), GetTileLength())
|
||||
Tile GetTile(int x, int y) const;
|
||||
|
||||
uint16_t GetTileLength() const { return TILEDLAYERBUFFER_TILE_SIZE; }
|
||||
|
||||
const nsIntRegion& GetValidRegion() const { return mValidRegion; }
|
||||
const nsIntRegion& GetLastPaintRegion() const { return mLastPaintRegion; }
|
||||
void SetLastPaintRegion(const nsIntRegion& aLastPaintRegion) {
|
||||
mLastPaintRegion = aLastPaintRegion;
|
||||
}
|
||||
|
||||
// Rounds the given coordinate down to the nearest tile boundary.
|
||||
int RoundDownToTileEdge(int aX) const { return aX - aX % GetTileLength(); }
|
||||
|
||||
protected:
|
||||
// The implementor should call Update() to change
|
||||
// the new valid region. This implementation will call
|
||||
// validateTile on each tile that is dirty, which is left
|
||||
// to the implementor.
|
||||
void Update(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion);
|
||||
|
||||
nsIntRegion mValidRegion;
|
||||
nsIntRegion mLastPaintRegion;
|
||||
|
||||
/**
|
||||
* mRetainedTiles is a rectangular buffer of mRetainedWidth x mRetainedHeight
|
||||
* stored as column major with the same origin as mValidRegion.GetBounds().
|
||||
* Any tile that does not intersect mValidRegion is a PlaceholderTile.
|
||||
* Only the region intersecting with mValidRegion should be read from a tile,
|
||||
* another other region is assumed to be uninitialized.
|
||||
*/
|
||||
nsTArray<Tile> mRetainedTiles;
|
||||
int mRetainedWidth; // in tiles
|
||||
int mRetainedHeight; // in tiles
|
||||
|
||||
private:
|
||||
TiledLayerBuffer(const TiledLayerBuffer&) MOZ_DELETE;
|
||||
|
||||
const Derived& AsDerived() const { return *static_cast<const Derived*>(this); }
|
||||
Derived& AsDerived() { return *static_cast<Derived*>(this); }
|
||||
|
||||
bool IsPlaceholder(Tile aTile) const { return aTile == AsDerived().GetPlaceholderTile(); }
|
||||
};
|
||||
|
||||
class BasicTiledLayerBuffer;
|
||||
|
||||
// Shadow layers may implement this interface in order to be notified when a
|
||||
// tiled layer buffer is updated.
|
||||
class TiledLayerComposer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Update the current retained layer with the updated layer data.
|
||||
* The BasicTiledLayerBuffer is expected to be in the ReadLock state
|
||||
* prior to this being called. aTiledBuffer is copy constructed and
|
||||
* is retained until it has been uploaded/copyed and unlocked.
|
||||
*/
|
||||
virtual void PaintedTiledLayerBuffer(const BasicTiledLayerBuffer* aTiledBuffer) = 0;
|
||||
};
|
||||
|
||||
template<typename Derived, typename Tile> Tile
|
||||
TiledLayerBuffer<Derived, Tile>::GetTile(const nsIntPoint& aTileOrigin) const
|
||||
{
|
||||
// TODO Cache firstTileOriginX/firstTileOriginY
|
||||
// Find the tile x/y of the first tile and the target tile relative to the (0, 0)
|
||||
// origin, the difference is the tile x/y relative to the start of the tile buffer.
|
||||
int firstTileX = mValidRegion.GetBounds().x / GetTileLength();
|
||||
int firstTileY = mValidRegion.GetBounds().y / GetTileLength();
|
||||
return GetTile(aTileOrigin.x / GetTileLength() - firstTileX,
|
||||
aTileOrigin.y / GetTileLength() - firstTileY);
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> Tile
|
||||
TiledLayerBuffer<Derived, Tile>::GetTile(int x, int y) const
|
||||
{
|
||||
int index = x * mRetainedHeight + y;
|
||||
return mRetainedTiles.SafeElementAt(index, AsDerived().GetPlaceholderTile());
|
||||
}
|
||||
|
||||
template<typename Derived, typename Tile> void
|
||||
TiledLayerBuffer<Derived, Tile>::Update(const nsIntRegion& aNewValidRegion,
|
||||
const nsIntRegion& aPaintRegion)
|
||||
{
|
||||
nsTArray<Tile> newRetainedTiles;
|
||||
nsTArray<Tile>& oldRetainedTiles = mRetainedTiles;
|
||||
const nsIntRect oldBound = mValidRegion.GetBounds();
|
||||
const nsIntRect newBound = aNewValidRegion.GetBounds();
|
||||
const nsIntPoint oldBufferOrigin(RoundDownToTileEdge(oldBound.x),
|
||||
RoundDownToTileEdge(oldBound.y));
|
||||
const nsIntPoint newBufferOrigin(RoundDownToTileEdge(newBound.x),
|
||||
RoundDownToTileEdge(newBound.y));
|
||||
const nsIntRegion& oldValidRegion = mValidRegion;
|
||||
const nsIntRegion& newValidRegion = aNewValidRegion;
|
||||
const int oldRetainedHeight = mRetainedHeight;
|
||||
|
||||
// Pass 1: Recycle valid content from the old buffer
|
||||
// Recycle tiles from the old buffer that contain valid regions.
|
||||
// Insert placeholders tiles if we have no valid area for that tile
|
||||
// which we will allocate in pass 2.
|
||||
// TODO: Add a tile pool to reduce new allocation
|
||||
int tileX = 0;
|
||||
int tileY;
|
||||
// Iterate over the new drawing bounds in steps of tiles.
|
||||
for (int x = newBound.x; x < newBound.XMost(); tileX++) {
|
||||
// Compute tileRect(x,y,width,height) in layer space coordinate
|
||||
// giving us the rect of the tile that hits the newBounds.
|
||||
int width = GetTileLength() - x % GetTileLength();
|
||||
if (x + width > newBound.XMost()) {
|
||||
width = newBound.x + newBound.width - x;
|
||||
}
|
||||
|
||||
tileY = 0;
|
||||
for (int y = newBound.y; y < newBound.YMost(); tileY++) {
|
||||
int height = GetTileLength() - y % GetTileLength();
|
||||
if (y + height > newBound.y + newBound.height) {
|
||||
height = newBound.y + newBound.height - y;
|
||||
}
|
||||
|
||||
const nsIntRect tileRect(x,y,width,height);
|
||||
if (oldValidRegion.Intersects(tileRect) && newValidRegion.Intersects(tileRect)) {
|
||||
// This old tiles contains some valid area so move it to the new tile
|
||||
// buffer. Replace the tile in the old buffer with a placeholder
|
||||
// to leave the old buffer index unaffected.
|
||||
int tileX = (x - oldBufferOrigin.x) / GetTileLength();
|
||||
int tileY = (y - oldBufferOrigin.y) / GetTileLength();
|
||||
int index = tileX * oldRetainedHeight + tileY;
|
||||
|
||||
NS_ABORT_IF_FALSE(!IsPlaceholder(oldRetainedTiles.
|
||||
SafeElementAt(index, AsDerived().GetPlaceholderTile())),
|
||||
"Expected tile");
|
||||
|
||||
Tile tileWithPartialValidContent = oldRetainedTiles[index];
|
||||
newRetainedTiles.AppendElement(tileWithPartialValidContent);
|
||||
|
||||
oldRetainedTiles[index] = AsDerived().GetPlaceholderTile();
|
||||
} else {
|
||||
// This tile is either:
|
||||
// 1) Outside the new valid region and will simply be an empty
|
||||
// placeholder forever.
|
||||
// 2) The old buffer didn't have any data for this tile. We postpone
|
||||
// the allocation of this tile after we've reused any tile with
|
||||
// valid content because then we know we can safely recycle
|
||||
// with taking from a tile that has recyclable content.
|
||||
newRetainedTiles.AppendElement(AsDerived().GetPlaceholderTile());
|
||||
}
|
||||
|
||||
y += height;
|
||||
}
|
||||
|
||||
x += width;
|
||||
}
|
||||
|
||||
// Keep track of the number of horizontal/vertical tiles
|
||||
// in the buffer so that we can easily look up a tile.
|
||||
mRetainedWidth = tileX;
|
||||
mRetainedHeight = tileY;
|
||||
|
||||
NS_ABORT_IF_FALSE(aNewValidRegion.Contains(aPaintRegion), "Painting a region outside the visible region");
|
||||
#ifdef DEBUG
|
||||
nsIntRegion oldAndPainted(oldValidRegion);
|
||||
oldAndPainted.Or(oldAndPainted, aPaintRegion);
|
||||
#endif
|
||||
NS_ABORT_IF_FALSE(oldAndPainted.Contains(newValidRegion), "newValidRegion has not been fully painted");
|
||||
|
||||
nsIntRegion regionToPaint(aPaintRegion);
|
||||
|
||||
// Pass 2: Validate
|
||||
// We know at this point that any tile in the new buffer that had valid content
|
||||
// from the previous buffer is placed correctly in the new buffer.
|
||||
// We know that any tile in the old buffer that isn't a place holder is
|
||||
// of no use and can be recycled.
|
||||
// We also know that any place holder tile in the new buffer must be
|
||||
// allocated.
|
||||
tileX = 0;
|
||||
for (int x = newBound.x; x < newBound.x + newBound.width; tileX++) {
|
||||
// Compute tileRect(x,y,width,height) in layer space coordinate
|
||||
// giving us the rect of the tile that hits the newBounds.
|
||||
int tileStartX = RoundDownToTileEdge(x);
|
||||
int width = GetTileLength() - x % GetTileLength();
|
||||
if (x + width > newBound.XMost())
|
||||
width = newBound.XMost() - x;
|
||||
|
||||
tileY = 0;
|
||||
for (int y = newBound.y; y < newBound.y + newBound.height; tileY++) {
|
||||
int tileStartY = RoundDownToTileEdge(y);
|
||||
int height = GetTileLength() - y % GetTileLength();
|
||||
if (y + height > newBound.YMost()) {
|
||||
height = newBound.YMost() - y;
|
||||
}
|
||||
|
||||
const nsIntRect tileRect(x, y, width, height);
|
||||
|
||||
nsIntRegion tileDrawRegion;
|
||||
tileDrawRegion.And(tileRect, regionToPaint);
|
||||
|
||||
if (tileDrawRegion.IsEmpty()) {
|
||||
// We have a tile but it doesn't hit the draw region
|
||||
// because we can reuse all of the content from the
|
||||
// previous buffer.
|
||||
#ifdef DEBUG
|
||||
int currTileX = (x - newBufferOrigin.x) / GetTileLength();
|
||||
int currTileY = (y - newBufferOrigin.y) / GetTileLength();
|
||||
int index = currTileX * mRetainedHeight + currTileY;
|
||||
NS_ABORT_IF_FALSE(!newValidRegion.Intersects(tileRect) ||
|
||||
!IsPlaceholder(newRetainedTiles.
|
||||
SafeElementAt(index, AsDerived().GetPlaceholderTile())),
|
||||
"If we don't draw a tile we shouldn't have a placeholder there.");
|
||||
#endif
|
||||
y += height;
|
||||
continue;
|
||||
}
|
||||
|
||||
int tileX = (x - newBufferOrigin.x) / GetTileLength();
|
||||
int tileY = (y - newBufferOrigin.y) / GetTileLength();
|
||||
int index = tileX * mRetainedHeight + tileY;
|
||||
NS_ABORT_IF_FALSE(index >= 0 && index < newRetainedTiles.Length(), "index out of range");
|
||||
Tile newTile = newRetainedTiles[index];
|
||||
while (IsPlaceholder(newTile) && oldRetainedTiles.Length() > 0) {
|
||||
AsDerived().SwapTiles(newTile, oldRetainedTiles[oldRetainedTiles.Length()-1]);
|
||||
oldRetainedTiles.RemoveElementAt(oldRetainedTiles.Length()-1);
|
||||
}
|
||||
|
||||
// We've done our best effort to recycle a tile but it can be null
|
||||
// in which case it's up to the derived class's ValidateTile()
|
||||
// implementation to allocate a new tile before drawing
|
||||
nsIntPoint tileOrigin(tileStartX, tileStartY);
|
||||
newTile = AsDerived().ValidateTile(newTile, nsIntPoint(tileStartX, tileStartY),
|
||||
tileDrawRegion);
|
||||
NS_ABORT_IF_FALSE(!IsPlaceholder(newTile), "index out of range");
|
||||
newRetainedTiles[index] = newTile;
|
||||
|
||||
y += height;
|
||||
}
|
||||
|
||||
x += width;
|
||||
}
|
||||
|
||||
// Throw away any tiles we didn't recycle
|
||||
// TODO: Add a tile pool
|
||||
while (oldRetainedTiles.Length() > 0) {
|
||||
Tile oldTile = oldRetainedTiles[oldRetainedTiles.Length()-1];
|
||||
oldRetainedTiles.RemoveElementAt(oldRetainedTiles.Length()-1);
|
||||
AsDerived().ReleaseTile(oldTile);
|
||||
}
|
||||
|
||||
mRetainedTiles = newRetainedTiles;
|
||||
mValidRegion = aNewValidRegion;
|
||||
mLastPaintRegion = aPaintRegion;
|
||||
}
|
||||
|
||||
} // layers
|
||||
} // mozilla
|
||||
|
||||
#endif // GFX_TILEDLAYERBUFFER_H
|
118
gfx/layers/basic/BasicImplData.h
Normal file
@ -0,0 +1,118 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_BASICIMPLDATA_H
|
||||
#define GFX_BASICIMPLDATA_H
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* This is the ImplData for all Basic layers. It also exposes methods
|
||||
* private to the Basic implementation that are common to all Basic layer types.
|
||||
* In particular, there is an internal Paint() method that we can use
|
||||
* to paint the contents of non-Thebes layers.
|
||||
*
|
||||
* The class hierarchy for Basic layers is like this:
|
||||
* BasicImplData
|
||||
* Layer | | |
|
||||
* | | | |
|
||||
* +-> ContainerLayer | | |
|
||||
* | | | | |
|
||||
* | +-> BasicContainerLayer <--+ | |
|
||||
* | | |
|
||||
* +-> ThebesLayer | |
|
||||
* | | | |
|
||||
* | +-> BasicThebesLayer <---------+ |
|
||||
* | |
|
||||
* +-> ImageLayer |
|
||||
* | |
|
||||
* +-> BasicImageLayer <--------------+
|
||||
*/
|
||||
class BasicImplData {
|
||||
public:
|
||||
BasicImplData() : mHidden(false),
|
||||
mClipToVisibleRegion(false),
|
||||
mDrawAtomically(false),
|
||||
mOperator(gfxContext::OPERATOR_OVER)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicImplData);
|
||||
}
|
||||
virtual ~BasicImplData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicImplData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Layers that paint themselves, such as ImageLayers, should paint
|
||||
* in response to this method call. aContext will already have been
|
||||
* set up to account for all the properties of the layer (transform,
|
||||
* opacity, etc).
|
||||
*/
|
||||
virtual void Paint(gfxContext* aContext) {}
|
||||
|
||||
/**
|
||||
* Like Paint() but called for ThebesLayers with the additional parameters
|
||||
* they need.
|
||||
* If mClipToVisibleRegion is set, then the layer must clip to its
|
||||
* effective visible region (snapped or unsnapped, it doesn't matter).
|
||||
*/
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback) {}
|
||||
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Implementations return true here if they *must* retain their
|
||||
* layer contents. This is true of shadowable layers with shadows,
|
||||
* because there's no target on which to composite directly in the
|
||||
* layer-publishing child process.
|
||||
*/
|
||||
virtual bool MustRetainContent() { return false; }
|
||||
|
||||
/**
|
||||
* Layers will get this call when their layer manager is destroyed, this
|
||||
* indicates they should clear resources they don't really need after their
|
||||
* LayerManager ceases to exist.
|
||||
*/
|
||||
virtual void ClearCachedResources() {}
|
||||
|
||||
/**
|
||||
* This variable is set by MarkLayersHidden() before painting. It indicates
|
||||
* that the layer should not be composited during this transaction.
|
||||
*/
|
||||
void SetHidden(bool aCovered) { mHidden = aCovered; }
|
||||
bool IsHidden() const { return false; }
|
||||
/**
|
||||
* This variable is set by MarkLayersHidden() before painting. This is
|
||||
* the operator to be used when compositing the layer in this transaction. It must
|
||||
* be OVER or SOURCE.
|
||||
*/
|
||||
void SetOperator(gfxContext::GraphicsOperator aOperator)
|
||||
{
|
||||
NS_ASSERTION(aOperator == gfxContext::OPERATOR_OVER ||
|
||||
aOperator == gfxContext::OPERATOR_SOURCE,
|
||||
"Bad composition operator");
|
||||
mOperator = aOperator;
|
||||
}
|
||||
gfxContext::GraphicsOperator GetOperator() const { return mOperator; }
|
||||
|
||||
bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
||||
void SetDrawAtomically(bool aDrawAtomically) { mDrawAtomically = aDrawAtomically; }
|
||||
|
||||
protected:
|
||||
bool mHidden;
|
||||
bool mClipToVisibleRegion;
|
||||
bool mDrawAtomically;
|
||||
gfxContext::GraphicsOperator mOperator;
|
||||
};
|
||||
|
||||
} // layers
|
||||
} // mozilla
|
||||
|
||||
#endif
|
@ -48,6 +48,7 @@
|
||||
#include "ipc/ShadowLayerChild.h"
|
||||
|
||||
#include "BasicLayers.h"
|
||||
#include "BasicImplData.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "RenderTrace.h"
|
||||
|
||||
@ -78,110 +79,6 @@ namespace layers {
|
||||
class BasicContainerLayer;
|
||||
class ShadowableLayer;
|
||||
|
||||
/**
|
||||
* This is the ImplData for all Basic layers. It also exposes methods
|
||||
* private to the Basic implementation that are common to all Basic layer types.
|
||||
* In particular, there is an internal Paint() method that we can use
|
||||
* to paint the contents of non-Thebes layers.
|
||||
*
|
||||
* The class hierarchy for Basic layers is like this:
|
||||
* BasicImplData
|
||||
* Layer | | |
|
||||
* | | | |
|
||||
* +-> ContainerLayer | | |
|
||||
* | | | | |
|
||||
* | +-> BasicContainerLayer <--+ | |
|
||||
* | | |
|
||||
* +-> ThebesLayer | |
|
||||
* | | | |
|
||||
* | +-> BasicThebesLayer <---------+ |
|
||||
* | |
|
||||
* +-> ImageLayer |
|
||||
* | |
|
||||
* +-> BasicImageLayer <--------------+
|
||||
*/
|
||||
class BasicImplData {
|
||||
public:
|
||||
BasicImplData() : mHidden(false),
|
||||
mClipToVisibleRegion(false),
|
||||
mDrawAtomically(false),
|
||||
mOperator(gfxContext::OPERATOR_OVER)
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicImplData);
|
||||
}
|
||||
virtual ~BasicImplData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BasicImplData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Layers that paint themselves, such as ImageLayers, should paint
|
||||
* in response to this method call. aContext will already have been
|
||||
* set up to account for all the properties of the layer (transform,
|
||||
* opacity, etc).
|
||||
*/
|
||||
virtual void Paint(gfxContext* aContext) {}
|
||||
|
||||
/**
|
||||
* Like Paint() but called for ThebesLayers with the additional parameters
|
||||
* they need.
|
||||
* If mClipToVisibleRegion is set, then the layer must clip to its
|
||||
* effective visible region (snapped or unsnapped, it doesn't matter).
|
||||
*/
|
||||
virtual void PaintThebes(gfxContext* aContext,
|
||||
LayerManager::DrawThebesLayerCallback aCallback,
|
||||
void* aCallbackData,
|
||||
ReadbackProcessor* aReadback) {}
|
||||
|
||||
virtual ShadowableLayer* AsShadowableLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Implementations return true here if they *must* retain their
|
||||
* layer contents. This is true of shadowable layers with shadows,
|
||||
* because there's no target on which to composite directly in the
|
||||
* layer-publishing child process.
|
||||
*/
|
||||
virtual bool MustRetainContent() { return false; }
|
||||
|
||||
/**
|
||||
* Layers will get this call when their layer manager is destroyed, this
|
||||
* indicates they should clear resources they don't really need after their
|
||||
* LayerManager ceases to exist.
|
||||
*/
|
||||
virtual void ClearCachedResources() {}
|
||||
|
||||
/**
|
||||
* This variable is set by MarkLayersHidden() before painting. It indicates
|
||||
* that the layer should not be composited during this transaction.
|
||||
*/
|
||||
void SetHidden(bool aCovered) { mHidden = aCovered; }
|
||||
bool IsHidden() const { return false; }
|
||||
/**
|
||||
* This variable is set by MarkLayersHidden() before painting. This is
|
||||
* the operator to be used when compositing the layer in this transaction. It must
|
||||
* be OVER or SOURCE.
|
||||
*/
|
||||
void SetOperator(gfxContext::GraphicsOperator aOperator)
|
||||
{
|
||||
NS_ASSERTION(aOperator == gfxContext::OPERATOR_OVER ||
|
||||
aOperator == gfxContext::OPERATOR_SOURCE,
|
||||
"Bad composition operator");
|
||||
mOperator = aOperator;
|
||||
}
|
||||
gfxContext::GraphicsOperator GetOperator() const { return mOperator; }
|
||||
|
||||
bool GetClipToVisibleRegion() { return mClipToVisibleRegion; }
|
||||
void SetClipToVisibleRegion(bool aClip) { mClipToVisibleRegion = aClip; }
|
||||
|
||||
void SetDrawAtomically(bool aDrawAtomically) { mDrawAtomically = aDrawAtomically; }
|
||||
|
||||
protected:
|
||||
bool mHidden;
|
||||
bool mClipToVisibleRegion;
|
||||
bool mDrawAtomically;
|
||||
gfxContext::GraphicsOperator mOperator;
|
||||
};
|
||||
|
||||
class AutoSetOperator {
|
||||
public:
|
||||
AutoSetOperator(gfxContext* aContext, gfxContext::GraphicsOperator aOperator) {
|
||||
@ -2117,53 +2014,13 @@ BasicLayerManager::CreateReadbackLayer()
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
class BasicShadowableThebesLayer;
|
||||
class BasicShadowableLayer : public ShadowableLayer
|
||||
BasicShadowableLayer::~BasicShadowableLayer()
|
||||
{
|
||||
public:
|
||||
BasicShadowableLayer()
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableLayer);
|
||||
if (HasShadow()) {
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
|
||||
~BasicShadowableLayer()
|
||||
{
|
||||
if (HasShadow()) {
|
||||
PLayerChild::Send__delete__(GetShadow());
|
||||
}
|
||||
MOZ_COUNT_DTOR(BasicShadowableLayer);
|
||||
}
|
||||
|
||||
void SetShadow(PLayerChild* aShadow)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)");
|
||||
mShadow = aShadow;
|
||||
}
|
||||
|
||||
virtual void SetBackBuffer(const SurfaceDescriptor& aBuffer)
|
||||
{
|
||||
NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks");
|
||||
}
|
||||
|
||||
virtual void SetBackBufferYUVImage(gfxSharedImageSurface* aYBuffer,
|
||||
gfxSharedImageSurface* aUBuffer,
|
||||
gfxSharedImageSurface* aVBuffer)
|
||||
{
|
||||
NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks");
|
||||
}
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
// This is an "emergency Disconnect()", called when the compositing
|
||||
// process has died. |mShadow| and our Shmem buffers are
|
||||
// automatically managed by IPDL, so we don't need to explicitly
|
||||
// free them here (it's hard to get that right on emergency
|
||||
// shutdown anyway).
|
||||
mShadow = nsnull;
|
||||
}
|
||||
|
||||
virtual BasicShadowableThebesLayer* AsThebes() { return nsnull; }
|
||||
};
|
||||
MOZ_COUNT_DTOR(BasicShadowableLayer);
|
||||
}
|
||||
|
||||
static ShadowableLayer*
|
||||
ToShadowable(Layer* aLayer)
|
||||
|
@ -278,6 +278,49 @@ private:
|
||||
LayerRefArray mKeepAlive;
|
||||
};
|
||||
|
||||
class BasicShadowableThebesLayer;
|
||||
class BasicShadowableLayer : public ShadowableLayer
|
||||
{
|
||||
public:
|
||||
BasicShadowableLayer()
|
||||
{
|
||||
MOZ_COUNT_CTOR(BasicShadowableLayer);
|
||||
}
|
||||
|
||||
~BasicShadowableLayer();
|
||||
|
||||
void SetShadow(PLayerChild* aShadow)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(!mShadow, "can't have two shadows (yet)");
|
||||
mShadow = aShadow;
|
||||
}
|
||||
|
||||
virtual void SetBackBuffer(const SurfaceDescriptor& aBuffer)
|
||||
{
|
||||
NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks");
|
||||
}
|
||||
|
||||
virtual void SetBackBufferYUVImage(gfxSharedImageSurface* aYBuffer,
|
||||
gfxSharedImageSurface* aUBuffer,
|
||||
gfxSharedImageSurface* aVBuffer)
|
||||
{
|
||||
NS_RUNTIMEABORT("if this default impl is called, |aBuffer| leaks");
|
||||
}
|
||||
|
||||
virtual void Disconnect()
|
||||
{
|
||||
// This is an "emergency Disconnect()", called when the compositing
|
||||
// process has died. |mShadow| and our Shmem buffers are
|
||||
// automatically managed by IPDL, so we don't need to explicitly
|
||||
// free them here (it's hard to get that right on emergency
|
||||
// shutdown anyway).
|
||||
mShadow = nsnull;
|
||||
}
|
||||
|
||||
virtual BasicShadowableThebesLayer* AsThebes() { return nsnull; }
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,10 @@ gfxPattern::SetMatrix(const gfxMatrix& matrix)
|
||||
cairo_pattern_set_matrix(mPattern, &mat);
|
||||
} else {
|
||||
mTransform = ToMatrix(matrix);
|
||||
// Cairo-pattern matrices specify the conversion from DrawTarget to pattern
|
||||
// space. Azure pattern matrices specify the conversion from pattern to
|
||||
// DrawTarget space.
|
||||
mTransform.Invert();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1265,15 +1265,6 @@ public:
|
||||
// clears that capture.
|
||||
static void ClearMouseCapture(nsIFrame* aFrame);
|
||||
|
||||
void SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight);
|
||||
bool IsScrollPositionClampingScrollPortSizeSet() {
|
||||
return mScrollPositionClampingScrollPortSizeSet;
|
||||
}
|
||||
nsSize GetScrollPositionClampingScrollPortSize() {
|
||||
NS_ASSERTION(mScrollPositionClampingScrollPortSizeSet, "asking for scroll port when its not set?");
|
||||
return mScrollPositionClampingScrollPortSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class nsRefreshDriver;
|
||||
|
||||
@ -1324,8 +1315,6 @@ protected:
|
||||
|
||||
bool mSuppressInterruptibleReflows;
|
||||
|
||||
bool mScrollPositionClampingScrollPortSizeSet;
|
||||
|
||||
// A list of weak frames. This is a pointer to the last item in the list.
|
||||
nsWeakFrame* mWeakFrames;
|
||||
|
||||
@ -1344,8 +1333,6 @@ protected:
|
||||
float mXResolution;
|
||||
float mYResolution;
|
||||
|
||||
nsSize mScrollPositionClampingScrollPortSize;
|
||||
|
||||
static nsIContent* gKeyDownTarget;
|
||||
};
|
||||
|
||||
|
@ -831,8 +831,6 @@ PresShell::PresShell()
|
||||
mYResolution = 1.0;
|
||||
mViewportOverridden = false;
|
||||
|
||||
mScrollPositionClampingScrollPortSizeSet = false;
|
||||
|
||||
static bool addedSynthMouseMove = false;
|
||||
if (!addedSynthMouseMove) {
|
||||
Preferences::AddBoolVarCache(&sSynthMouseMove,
|
||||
@ -9149,10 +9147,3 @@ PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
/* clear = */false);
|
||||
}
|
||||
|
||||
void
|
||||
nsIPresShell::SetScrollPositionClampingScrollPortSize(nscoord aWidth, nscoord aHeight)
|
||||
{
|
||||
mScrollPositionClampingScrollPortSizeSet = true;
|
||||
mScrollPositionClampingScrollPortSize.width = aWidth;
|
||||
mScrollPositionClampingScrollPortSize.height = aHeight;
|
||||
}
|
||||
|
@ -1645,7 +1645,7 @@ Clamp(nscoord aLower, nscoord aVal, nscoord aUpper)
|
||||
nsPoint
|
||||
nsGfxScrollFrameInner::ClampScrollPosition(const nsPoint& aPt) const
|
||||
{
|
||||
nsRect range = GetScrollRangeForClamping();
|
||||
nsRect range = GetScrollRange();
|
||||
return nsPoint(Clamp(range.x, aPt.x, range.XMost()),
|
||||
Clamp(range.y, aPt.y, range.YMost()));
|
||||
}
|
||||
@ -1971,7 +1971,7 @@ nsGfxScrollFrameInner::RestrictToDevPixels(const nsPoint& aPt,
|
||||
// pixels. But we also need to make sure that our position remains
|
||||
// inside the allowed region.
|
||||
if (aShouldClamp) {
|
||||
nsRect scrollRange = GetScrollRangeForClamping();
|
||||
nsRect scrollRange = GetScrollRange();
|
||||
*aPtDevPx = nsIntPoint(ClampInt(scrollRange.x, aPt.x, scrollRange.XMost(), appUnitsPerDevPixel),
|
||||
ClampInt(scrollRange.y, aPt.y, scrollRange.YMost(), appUnitsPerDevPixel));
|
||||
} else {
|
||||
@ -2326,16 +2326,10 @@ AlignToDevPixelRoundingToZero(nscoord aVal, PRInt32 aAppUnitsPerDevPixel)
|
||||
|
||||
nsRect
|
||||
nsGfxScrollFrameInner::GetScrollRange() const
|
||||
{
|
||||
return GetScrollRange(mScrollPort.width, mScrollPort.height);
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsGfxScrollFrameInner::GetScrollRange(nscoord aWidth, nscoord aHeight) const
|
||||
{
|
||||
nsRect range = GetScrolledRect();
|
||||
range.width -= aWidth;
|
||||
range.height -= aHeight;
|
||||
range.width -= mScrollPort.width;
|
||||
range.height -= mScrollPort.height;
|
||||
|
||||
nsPresContext* presContext = mOuter->PresContext();
|
||||
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
@ -2348,17 +2342,6 @@ nsGfxScrollFrameInner::GetScrollRange(nscoord aWidth, nscoord aHeight) const
|
||||
return range;
|
||||
}
|
||||
|
||||
nsRect
|
||||
nsGfxScrollFrameInner::GetScrollRangeForClamping() const
|
||||
{
|
||||
nsIPresShell* presShell = mOuter->PresContext()->PresShell();
|
||||
if (presShell->IsScrollPositionClampingScrollPortSizeSet()) {
|
||||
nsSize size = presShell->GetScrollPositionClampingScrollPortSize();
|
||||
return GetScrollRange(size.width, size.height);
|
||||
}
|
||||
return GetScrollRange();
|
||||
}
|
||||
|
||||
static void
|
||||
AdjustForWholeDelta(PRInt32 aDelta, nscoord* aCoord)
|
||||
{
|
||||
|
@ -178,12 +178,7 @@ public:
|
||||
return pt;
|
||||
}
|
||||
nsRect GetScrollRange() const;
|
||||
// Get the scroll range assuming the scrollport has size (aWidth, aHeight).
|
||||
nsRect GetScrollRange(nscoord aWidth, nscoord aHeight) const;
|
||||
protected:
|
||||
nsRect GetScrollRangeForClamping() const;
|
||||
|
||||
public:
|
||||
nsPoint RestrictToDevPixels(const nsPoint& aPt, nsIntPoint* aPtDevPx, bool aShouldClamp) const;
|
||||
nsPoint ClampScrollPosition(const nsPoint& aPt) const;
|
||||
static void AsyncScrollCallback(nsITimer *aTimer, void* anInstance);
|
||||
|
19
layout/reftests/bidi/bdi-element-ref.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
From WebKit <a href='https://bugs.webkit.org/show_bug.cgi?id=50913'>bug 50913</a>
|
||||
</p>
|
||||
<p>
|
||||
In this example, usernames are shown along with the number of posts that the user has submitted. If the bdi element were not used, the username of the Arabic user would end up confusing the text (the bidirectional algorithm would put the colon and the number "3" next to the word "User" rather than next to the word "posts").
|
||||
</p>
|
||||
<ul>
|
||||
<li><bdo dir="ltr">User jcranmer: 12 posts.</bdo>
|
||||
<li><bdo dir="ltr">User hober: 5 posts.</bdo>
|
||||
<li><bdo dir="ltr">User نايإ: 3 posts.</bdo>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
19
layout/reftests/bidi/bdi-element.html
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
From WebKit <a href='https://bugs.webkit.org/show_bug.cgi?id=50913'>bug 50913</a>
|
||||
</p>
|
||||
<p>
|
||||
In this example, usernames are shown along with the number of posts that the user has submitted. If the bdi element were not used, the username of the Arabic user would end up confusing the text (the bidirectional algorithm would put the colon and the number "3" next to the word "User" rather than next to the word "posts").
|
||||
</p>
|
||||
<ul>
|
||||
<li>User <bdi>jcranmer</bdi>: 12 posts.
|
||||
<li>User <bdi>hober</bdi>: 5 posts.
|
||||
<li>User <bdi>إيان</bdi>: 3 posts.
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -1,3 +1,4 @@
|
||||
fails-if(Android) == bdi-element.html bdi-element-ref.html # sub-pixel AA
|
||||
== bidi-000.html bidi-000-ref.html
|
||||
== bidi-001.html bidi-001-ref.html
|
||||
== bidi-001-j.html bidi-001-ref.html
|
||||
@ -32,6 +33,13 @@ random-if(cocoaWidget) == mirroring-02.html mirroring-02-ref.html
|
||||
== mixedChartype-03-j.html mixedChartype-03-ref.html
|
||||
== unicode-bidi-anonymous-001.html unicode-bidi-anonymous-001-ref.html
|
||||
== unicode-bidi-anonymous-002.html unicode-bidi-anonymous-002-ref.html
|
||||
fails == unicode-bidi-isolate-basic.html unicode-bidi-isolate-basic-ref.html # bug 712600
|
||||
fails == unicode-bidi-isolate-aharon.html unicode-bidi-isolate-aharon-ref.html # bug 712600
|
||||
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated) == unicode-bidi-plaintext.html unicode-bidi-plaintext-ref.html # sub-pixel AA
|
||||
== unicode-bidi-plaintext-textarea-1.html unicode-bidi-plaintext-textarea-ref.html
|
||||
== unicode-bidi-plaintext-textarea-2.html unicode-bidi-plaintext-textarea-ref.html
|
||||
== unicode-bidi-plaintext-textarea-3.html unicode-bidi-plaintext-textarea-ref.html
|
||||
== unicode-bidi-plaintext-textarea-4.html unicode-bidi-plaintext-textarea-ref.html
|
||||
== with-first-letter-1a.html with-first-letter-1-ref.html
|
||||
== with-first-letter-1b.html with-first-letter-1-ref.html
|
||||
random-if(cocoaWidget) == with-first-letter-2a.html with-first-letter-2-ref.html # bug 734313
|
||||
|
69
layout/reftests/bidi/unicode-bidi-isolate-aharon-ref.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>Test cases for unicode-bidi:isolate</title>
|
||||
<style>
|
||||
</style>
|
||||
</head><body>
|
||||
opposite-to-base isolate followed by number.
|
||||
<div>
|
||||
<div class="reference">
|
||||
<span dir="ltr">א</span> (3 reviews)
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
opposite-to-base isolate with opposite-to-base text before it with neutrals in between.
|
||||
<div>
|
||||
<div class="reference">
|
||||
<span dir="ltr">א</span>: <span dir="ltr">ב</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
opposite-to-base isolate with opposite-to-base text before it and nothing in between.
|
||||
<div>
|
||||
<div class="reference">
|
||||
<bdo dir="ltr">אב</bdo>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
two opposite-to-base isolates with neutrals in between.
|
||||
<div>
|
||||
<div class="reference">
|
||||
<span dir="ltr">א</span> = <span dir="ltr">ב</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
two opposite-to-base isolates with nothing in between.
|
||||
<div>
|
||||
<div class="reference">
|
||||
<bdo dir="ltr">אב</bdo>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
same-as-base isolate preceded by opposite-to-base text and followed by number
|
||||
<div dir="rtl">
|
||||
<div class="reference">
|
||||
see <span dir="ltr">א</span><sup>3</sup>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
same-as-base isolate surrounded by opposite-to-base text
|
||||
<div dir="rtl">
|
||||
<div class="reference">
|
||||
with <span dir="ltr">א</span>=<span dir="ltr">ב</span> everywhere
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
chimeric isolate surrounded by chimeric text
|
||||
<div>
|
||||
<div class="reference">
|
||||
about that <span dir="ltr">א</span> - ב
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
nested chimeric isolates surrounded by chimeric text
|
||||
<div>
|
||||
<div class="reference">
|
||||
about that strange <span dir="ltr">א</span> - <span dir="ltr">ב</span> - ג
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
74
layout/reftests/bidi/unicode-bidi-isolate-aharon.html
Normal file
@ -0,0 +1,74 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>Test cases for unicode-bidi:isolate</title>
|
||||
<style>
|
||||
.isolate {
|
||||
unicode-bidi: -webkit-isolate;
|
||||
unicode-bidi: -moz-isolate;
|
||||
unicode-bidi: isolate;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
opposite-to-base isolate followed by number.
|
||||
<div>
|
||||
<div class="test">
|
||||
<span class="isolate">א</span> (3 reviews)
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
opposite-to-base isolate with opposite-to-base text before it with neutrals in between.
|
||||
<div>
|
||||
<div class="test">
|
||||
א: <span class="isolate">ב</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
opposite-to-base isolate with opposite-to-base text before it and nothing in between.
|
||||
<div>
|
||||
<div class="test">
|
||||
א<span class="isolate">ב</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
two opposite-to-base isolates with neutrals in between.
|
||||
<div>
|
||||
<div class="test">
|
||||
<span class="isolate">א</span> = <span class="isolate">ב</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
two opposite-to-base isolates with nothing in between.
|
||||
<div>
|
||||
<div class="test">
|
||||
<span class="isolate">א</span><span class="isolate">ב</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
same-as-base isolate preceded by opposite-to-base text and followed by number
|
||||
<div dir="rtl">
|
||||
<div class="test">
|
||||
see <span class="isolate">א</span><sup>3</sup>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
same-as-base isolate surrounded by opposite-to-base text
|
||||
<div dir="rtl">
|
||||
<div class="test">
|
||||
with <span class="isolate">א</span>=<span class="isolate">ב</span> everywhere
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
chimeric isolate surrounded by chimeric text
|
||||
<div>
|
||||
<div class="test">
|
||||
about <span class="isolate">that א</span> - ב
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
nested chimeric isolates surrounded by chimeric text
|
||||
<div>
|
||||
<div class="test">
|
||||
about <span class="isolate">that <span class="isolate">strange א</span> - ב</span> - ג
|
||||
</div>
|
||||
</div>
|
||||
</body></html>
|
22
layout/reftests/bidi/unicode-bidi-isolate-basic-ref.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="unicode-bidi-isolate-basic.js"></script>
|
||||
<style>
|
||||
.resultsDiv {
|
||||
-moz-column-width: 3em;
|
||||
-webkit-column-width: 3em;
|
||||
-moz-column-gap: 5em;
|
||||
-webkit-column-gap: 5em;
|
||||
text-align: left;
|
||||
}
|
||||
.enclosed { display: inline-block; }
|
||||
</style>
|
||||
</head>
|
||||
<body onload="buildTable();">
|
||||
<div id="resultsContainer" style="position: relative">
|
||||
<div id="elem" class="resultsDiv"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
22
layout/reftests/bidi/unicode-bidi-isolate-basic.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<script type="text/javascript" src="unicode-bidi-isolate-basic.js"></script>
|
||||
<style>
|
||||
.resultsDiv {
|
||||
-moz-column-width: 3em;
|
||||
-webkit-column-width: 3em;
|
||||
-moz-column-gap: 5em;
|
||||
-webkit-column-gap: 5em;
|
||||
text-align: left;
|
||||
}
|
||||
.enclosed { unicode-bidi: -moz-isolate; }
|
||||
</style>
|
||||
</head>
|
||||
<body onload="buildTable()">
|
||||
<div id="resultsContainer" style="position: relative">
|
||||
<div id="elem" class="resultsDiv"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
44
layout/reftests/bidi/unicode-bidi-isolate-basic.js
Normal file
@ -0,0 +1,44 @@
|
||||
function buildTable()
|
||||
{
|
||||
var seed = 0;
|
||||
|
||||
var neutrals = ['"', ")", "("];
|
||||
var strongRTLs = ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ז'];
|
||||
var strongLTRs = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
|
||||
var neutral = function() { return neutrals[seed++ % neutrals.length]; }
|
||||
var strongRTL = function() { return strongRTLs[seed++ % strongRTLs.length]; }
|
||||
var strongLTR = function() { return strongLTRs[seed++ % strongLTRs.length]; }
|
||||
var charClassExamples = [neutral, strongRTL, strongLTR];
|
||||
var possibleDirs = ['ltr', 'rtl'];
|
||||
|
||||
var elem=document.getElementById("elem");
|
||||
for (outerDirIndex in possibleDirs) {
|
||||
var outerDir = possibleDirs[outerDirIndex];
|
||||
for (beforeSpanIndex in charClassExamples) {
|
||||
var beforeSpan = charClassExamples[beforeSpanIndex];
|
||||
for (spanDirIndex in possibleDirs) {
|
||||
var spanDir = possibleDirs[spanDirIndex];
|
||||
for (inSpanIndex in charClassExamples) {
|
||||
var inSpan = charClassExamples[inSpanIndex];
|
||||
for (afterSpanIndex in charClassExamples) {
|
||||
var afterSpan = charClassExamples[afterSpanIndex];
|
||||
function caseWithStyle() {
|
||||
seed = 0;
|
||||
var outerDiv = document.createElement("div");
|
||||
outerDiv.dir = outerDir;
|
||||
outerDiv.appendChild(document.createTextNode(beforeSpan()));
|
||||
var span = document.createElement("span");
|
||||
span.dir = spanDir;
|
||||
span.setAttribute("class", "enclosed")
|
||||
span.appendChild(document.createTextNode(inSpan()));
|
||||
outerDiv.appendChild(span);
|
||||
outerDiv.appendChild(document.createTextNode(afterSpan()));
|
||||
return outerDiv;
|
||||
}
|
||||
elem.appendChild(caseWithStyle());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
layout/reftests/bidi/unicode-bidi-plaintext-ref.html
Normal file
@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
!hello.<br>
|
||||
<span dir=rtl>
|
||||
!שלום.
|
||||
</span><br>
|
||||
<span dir=ltr>
|
||||
hello, לוי!
|
||||
</span><br>
|
||||
<span dir=rtl>
|
||||
שלום, WebKit!</span><br>
|
||||
<pre>
|
||||
a
|
||||
(
|
||||
!WebKit ,שלום
|
||||
hello, לוי!
|
||||
)
|
||||
</pre>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
17
layout/reftests/bidi/unicode-bidi-plaintext-textarea-1.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>unicode-bidi:plaintext</title>
|
||||
<style>
|
||||
textarea { text-align: left; resize: none; }
|
||||
</style>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
</head><body>
|
||||
<div>
|
||||
The exclamation mark should be on the left side of the first line
|
||||
and on the right side of the second line.
|
||||
</div>
|
||||
<textarea rows=4 cols=50 dir=auto>
|
||||
שלום!
|
||||
hello!
|
||||
</textarea>
|
||||
</body></html>
|
22
layout/reftests/bidi/unicode-bidi-plaintext-textarea-2.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>unicode-bidi:plaintext</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<style>
|
||||
.plaintext {
|
||||
unicode-bidi:-webkit-plaintext;
|
||||
unicode-bidi:-moz-plaintext;
|
||||
unicode-bidi:plaintext;
|
||||
}
|
||||
textarea { text-align: left; resize: none; }
|
||||
</style>
|
||||
</head><body>
|
||||
<div>
|
||||
The exclamation mark should be on the left side of the first line
|
||||
and on the right side of the second line.
|
||||
</div>
|
||||
<textarea rows=4 cols=50 class="plaintext">
|
||||
שלום!
|
||||
hello!
|
||||
</textarea>
|
||||
</body></html>
|
22
layout/reftests/bidi/unicode-bidi-plaintext-textarea-3.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>unicode-bidi:plaintext</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<style>
|
||||
.plaintext {
|
||||
unicode-bidi:-webkit-plaintext;
|
||||
unicode-bidi:-moz-plaintext;
|
||||
unicode-bidi:plaintext;
|
||||
}
|
||||
textarea { text-align: left; resize: none; }
|
||||
</style>
|
||||
</head><body>
|
||||
<div>
|
||||
The exclamation mark should be on the left side of the first line
|
||||
and on the right side of the second line.
|
||||
</div>
|
||||
<textarea rows=4 cols=50 dir="ltr" class="plaintext">
|
||||
שלום!
|
||||
hello!
|
||||
</textarea>
|
||||
</body></html>
|
22
layout/reftests/bidi/unicode-bidi-plaintext-textarea-4.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head>
|
||||
<title>unicode-bidi:plaintext</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<style>
|
||||
.plaintext {
|
||||
unicode-bidi:-webkit-plaintext;
|
||||
unicode-bidi:-moz-plaintext;
|
||||
unicode-bidi:plaintext;
|
||||
}
|
||||
textarea { text-align: left; resize: none; }
|
||||
</style>
|
||||
</head><body>
|
||||
<div>
|
||||
The exclamation mark should be on the left side of the first line
|
||||
and on the right side of the second line.
|
||||
</div>
|
||||
<textarea rows=4 cols=50 dir="rtl" class="plaintext">
|
||||
שלום!
|
||||
hello!
|
||||
</textarea>
|
||||
</body></html>
|
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>unicode-bidi:plaintext</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<style>
|
||||
textarea { resize: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
The exclamation mark should be on the left side of the first line
|
||||
and on the right side of the second line.
|
||||
</div>
|
||||
<textarea rows=4 cols=50 dir=ltr>
|
||||
‫שלום!‬
|
||||
‪hello!‬
|
||||
</textarea>
|
||||
</body></html>
|
27
layout/reftests/bidi/unicode-bidi-plaintext.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<style>
|
||||
div, pre { text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div style="unicode-bidi: -webkit-plaintext; unicode-bidi: -moz-plaintext; unicode-bidi: plaintext;">
|
||||
!hello.
|
||||
<br>
|
||||
!שלום.
|
||||
<br>
|
||||
hello, לוי!
|
||||
<br>
|
||||
שלום, WebKit!
|
||||
</div>
|
||||
<pre dir="auto">
|
||||
a
|
||||
(
|
||||
שלום, WebKit!
|
||||
hello, לוי!
|
||||
)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -141,6 +141,7 @@ _TEST_FILES = test_acid3_test46.html \
|
||||
test_computed_style_no_pseudo.html \
|
||||
test_css_cross_domain.html \
|
||||
test_css_eof_handling.html \
|
||||
test_default_bidi_css.html \
|
||||
test_descriptor_storage.html \
|
||||
test_descriptor_syntax_errors.html \
|
||||
test_dont_use_document_colors.html \
|
||||
|
79
layout/style/test/test_default_bidi_css.html
Normal file
@ -0,0 +1,79 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug </title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for default bidi css **/
|
||||
function styleOf(name, attributes) {
|
||||
var element = document.createElement(name);
|
||||
for (var name in attributes) {
|
||||
var value = attributes[name];
|
||||
element.setAttribute(name, value);
|
||||
}
|
||||
return getComputedStyle(element);
|
||||
}
|
||||
|
||||
var tests = [
|
||||
['div', {}, 'ltr', '-moz-isolate'],
|
||||
['div', {'dir': 'ltr'}, 'ltr', '-moz-isolate'],
|
||||
['div', {'dir': 'rtl'}, 'rtl', '-moz-isolate'],
|
||||
['div', {'dir': 'auto'}, 'ltr', '-moz-isolate'],
|
||||
['div', {'dir': ''}, 'ltr', '-moz-isolate'],
|
||||
|
||||
['span', {}, 'ltr', 'normal'],
|
||||
['span', {'dir': 'ltr'}, 'ltr', 'embed'],
|
||||
['span', {'dir': 'rtl'}, 'rtl', 'embed'],
|
||||
['span', {'dir': 'auto'}, 'ltr', '-moz-isolate'],
|
||||
['span', {'dir': ''}, 'ltr', 'normal'],
|
||||
|
||||
['bdi', {}, 'ltr', '-moz-isolate'],
|
||||
['bdi', {'dir': 'ltr'}, 'ltr', '-moz-isolate'],
|
||||
['bdi', {'dir': 'rtl'}, 'rtl', '-moz-isolate'],
|
||||
['bdi', {'dir': 'auto'}, 'ltr', '-moz-isolate'],
|
||||
['bdi', {'dir': ''}, 'ltr', '-moz-isolate'],
|
||||
|
||||
['output', {}, 'ltr', '-moz-isolate'],
|
||||
['output', {'dir': 'ltr'}, 'ltr', '-moz-isolate'],
|
||||
['output', {'dir': 'rtl'}, 'rtl', '-moz-isolate'],
|
||||
['output', {'dir': 'auto'}, 'ltr', '-moz-isolate'],
|
||||
['output', {'dir': ''}, 'ltr', '-moz-isolate'],
|
||||
|
||||
['bdo', {}, 'ltr', 'bidi-override'],
|
||||
['bdo', {'dir': 'ltr'}, 'ltr', 'bidi-override'],
|
||||
['bdo', {'dir': 'rtl'}, 'rtl', 'bidi-override'],
|
||||
['bdo', {'dir': 'auto'}, 'ltr', '-moz-isolate bidi-override'],
|
||||
['bdo', {'dir': ''}, 'ltr', 'bidi-override'],
|
||||
|
||||
['textarea', {}, 'ltr', 'normal'],
|
||||
['textarea', {'dir': 'ltr'}, 'ltr', 'embed'],
|
||||
['textarea', {'dir': 'rtl'}, 'rtl', 'embed'],
|
||||
['textarea', {'dir': 'auto'}, 'ltr', '-moz-plaintext'],
|
||||
['textarea', {'dir': ''}, 'ltr', 'normal'],
|
||||
|
||||
['pre', {}, 'ltr', '-moz-isolate'],
|
||||
['pre', {'dir': 'ltr'}, 'ltr', '-moz-isolate'],
|
||||
['pre', {'dir': 'rtl'}, 'rtl', '-moz-isolate'],
|
||||
['pre', {'dir': 'auto'}, 'ltr', '-moz-plaintext'],
|
||||
['pre', {'dir': ''}, 'ltr', '-moz-isolate'],
|
||||
].forEach(function (test) {
|
||||
var style = styleOf(test[0], test[1]);
|
||||
is(style.direction, test[2], "default value for direction");
|
||||
is(style.unicodeBidi, test[3], "default value for unicode-bidi");
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -218,6 +218,7 @@ sa_stream_open(sa_stream_t *s) {
|
||||
|
||||
s->at_class = init_jni_bindings(jenv);
|
||||
if (!s->at_class) {
|
||||
(*jenv)->PopLocalFrame(jenv, NULL);
|
||||
return SA_ERROR_NO_DEVICE;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,9 @@ public class BrowserToolbar {
|
||||
} else {
|
||||
mProgressSpinner.stop();
|
||||
setStopVisibility(false);
|
||||
setFavicon(Tabs.getInstance().getSelectedTab().getFavicon());
|
||||
Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
||||
if (selectedTab != null)
|
||||
setFavicon(selectedTab.getFavicon());
|
||||
Log.i(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - Throbber stop");
|
||||
}
|
||||
}
|
||||
|
@ -670,6 +670,7 @@ abstract public class GeckoApp
|
||||
tab.updateSecurityMode("unknown");
|
||||
tab.removeTransientDoorHangers();
|
||||
tab.setHasTouchListeners(false);
|
||||
tab.setCheckerboardColor(Color.WHITE);
|
||||
|
||||
maybeCancelFaviconLoad(tab);
|
||||
|
||||
@ -829,14 +830,20 @@ abstract public class GeckoApp
|
||||
final String title = message.getString("title");
|
||||
final String backgroundColor = message.getString("bgColor");
|
||||
handleContentLoaded(tabId, uri, title);
|
||||
if (getLayerController() != null) {
|
||||
if (backgroundColor != null) {
|
||||
getLayerController().setCheckerboardColor(backgroundColor);
|
||||
} else {
|
||||
// Default to black if no color is given
|
||||
getLayerController().setCheckerboardColor(0);
|
||||
}
|
||||
Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
if (backgroundColor != null) {
|
||||
tab.setCheckerboardColor(backgroundColor);
|
||||
} else {
|
||||
// Default to white if no color is given
|
||||
tab.setCheckerboardColor(Color.WHITE);
|
||||
}
|
||||
|
||||
// Sync up the LayerController and the tab if the tab's
|
||||
// currently displayed.
|
||||
if (getLayerController() != null && Tabs.getInstance().isSelectedTab(tab)) {
|
||||
getLayerController().setCheckerboardColor(tab.getCheckerboardColor());
|
||||
}
|
||||
|
||||
Log.i(LOGTAG, "URI - " + uri + ", title - " + title);
|
||||
} else if (event.equals("DOMTitleChanged")) {
|
||||
final int tabId = message.getInt("tabID");
|
||||
@ -1639,7 +1646,9 @@ abstract public class GeckoApp
|
||||
}
|
||||
|
||||
mRestoreSession |= getProfile().shouldRestoreSession();
|
||||
if (passedUri == null || passedUri.equals("about:home")) {
|
||||
|
||||
boolean isExternalURL = passedUri != null && !passedUri.equals("about:home");
|
||||
if (!isExternalURL) {
|
||||
// show about:home if we aren't restoring previous session
|
||||
if (!mRestoreSession) {
|
||||
mBrowserToolbar.updateTabCount(1);
|
||||
@ -1649,6 +1658,8 @@ abstract public class GeckoApp
|
||||
mBrowserToolbar.updateTabCount(1);
|
||||
}
|
||||
|
||||
mBrowserToolbar.setProgressVisibility(isExternalURL || mRestoreSession);
|
||||
|
||||
// Start migrating as early as possible, can do this in
|
||||
// parallel with Gecko load.
|
||||
checkMigrateProfile();
|
||||
|
@ -529,14 +529,17 @@ public class GeckoAppShell
|
||||
final int width, final int height) {
|
||||
getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
final Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
if (tab == null)
|
||||
return;
|
||||
try {
|
||||
final Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
if (tab == null)
|
||||
return;
|
||||
|
||||
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
b.copyPixelsFromBuffer(data);
|
||||
freeDirectBuffer(data);
|
||||
GeckoApp.mAppContext.processThumbnail(tab, b, null);
|
||||
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
b.copyPixelsFromBuffer(data);
|
||||
GeckoApp.mAppContext.processThumbnail(tab, b, null);
|
||||
} finally {
|
||||
freeDirectBuffer(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -481,6 +481,10 @@ RES_DRAWABLE_XHDPI_V11 = \
|
||||
res/drawable-xhdpi-v11/address_bar_texture_port.png \
|
||||
res/drawable-xhdpi-v11/address_bar_url_bg.9.png \
|
||||
res/drawable-xhdpi-v11/address_bar_url_outline.9.png \
|
||||
res/drawable-xhdpi-v11/doorhanger_arrow.png \
|
||||
res/drawable-xhdpi-v11/doorhanger_bg.9.png \
|
||||
res/drawable-xhdpi-v11/doorhanger_shadow_bg.9.png \
|
||||
res/drawable-xhdpi-v11/doorhanger_popup_bg.9.png \
|
||||
res/drawable-xhdpi-v11/urlbar_stop.png \
|
||||
res/drawable-xhdpi-v11/site_security_identified.png \
|
||||
res/drawable-xhdpi-v11/site_security_verified.png \
|
||||
|
@ -40,6 +40,7 @@ package org.mozilla.gecko;
|
||||
import android.content.ContentResolver;
|
||||
import android.database.ContentObserver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
@ -58,6 +59,8 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public final class Tab {
|
||||
private static final String LOGTAG = "GeckoTab";
|
||||
@ -68,6 +71,7 @@ public final class Tab {
|
||||
private static float sDensity = 1;
|
||||
private static int sMinScreenshotWidth = 0;
|
||||
private static int sMinScreenshotHeight = 0;
|
||||
private static Pattern sColorPattern;
|
||||
private int mId;
|
||||
private String mUrl;
|
||||
private String mTitle;
|
||||
@ -89,6 +93,7 @@ public final class Tab {
|
||||
private HashMap<Surface, Layer> mPluginLayers;
|
||||
private ContentResolver mContentResolver;
|
||||
private ContentObserver mContentObserver;
|
||||
private int mCheckerboardColor = Color.WHITE;
|
||||
private int mState;
|
||||
|
||||
public static final int STATE_DELAYED = 0;
|
||||
@ -561,4 +566,36 @@ public final class Tab {
|
||||
public Layer removePluginLayer(Surface surface) {
|
||||
return mPluginLayers.remove(surface);
|
||||
}
|
||||
|
||||
public int getCheckerboardColor() {
|
||||
return mCheckerboardColor;
|
||||
}
|
||||
|
||||
/** Sets a new color for the checkerboard. */
|
||||
public void setCheckerboardColor(int color) {
|
||||
mCheckerboardColor = color;
|
||||
}
|
||||
|
||||
/** Parses and sets a new color for the checkerboard. */
|
||||
public void setCheckerboardColor(String newColor) {
|
||||
setCheckerboardColor(parseColorFromGecko(newColor));
|
||||
}
|
||||
|
||||
// Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
|
||||
// cannot be parsed, returns white.
|
||||
private static int parseColorFromGecko(String string) {
|
||||
if (sColorPattern == null) {
|
||||
sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
|
||||
}
|
||||
|
||||
Matcher matcher = sColorPattern.matcher(string);
|
||||
if (!matcher.matches()) {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
int r = Integer.parseInt(matcher.group(1));
|
||||
int g = Integer.parseInt(matcher.group(2));
|
||||
int b = Integer.parseInt(matcher.group(3));
|
||||
return Color.rgb(r, g, b);
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ import android.util.Log;
|
||||
import android.view.View;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
|
||||
public class GeckoLayerClient implements GeckoEventResponder,
|
||||
LayerView.Listener {
|
||||
@ -329,6 +330,7 @@ public class GeckoLayerClient implements GeckoEventResponder,
|
||||
currentMetrics.setZoomFactor(zoom);
|
||||
currentMetrics.setPageSize(new FloatSize(pageWidth, pageHeight), new FloatSize(cssPageWidth, cssPageHeight));
|
||||
mLayerController.setViewportMetrics(currentMetrics);
|
||||
mLayerController.setCheckerboardColor(Tabs.getInstance().getSelectedTab().getCheckerboardColor());
|
||||
// At this point, we have just switched to displaying a different document than we
|
||||
// we previously displaying. This means we need to abort any panning/zooming animations
|
||||
// that are in progress and send an updated display port request to browser.js as soon
|
||||
|
@ -52,8 +52,6 @@ import android.graphics.RectF;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.View.OnTouchListener;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* The layer controller manages a tile that represents the visible page. It does panning and
|
||||
@ -91,13 +89,11 @@ public class LayerController {
|
||||
private GeckoLayerClient mLayerClient; /* The layer client. */
|
||||
|
||||
/* The new color for the checkerboard. */
|
||||
private int mCheckerboardColor;
|
||||
private int mCheckerboardColor = Color.WHITE;
|
||||
private boolean mCheckerboardShouldShowChecks;
|
||||
|
||||
private boolean mForceRedraw;
|
||||
|
||||
private static Pattern sColorPattern;
|
||||
|
||||
public LayerController(Context context) {
|
||||
mContext = context;
|
||||
|
||||
@ -359,29 +355,4 @@ public class LayerController {
|
||||
mCheckerboardColor = newColor;
|
||||
mView.requestRender();
|
||||
}
|
||||
|
||||
/** Parses and sets a new color for the checkerboard. */
|
||||
public void setCheckerboardColor(String newColor) {
|
||||
setCheckerboardColor(parseColorFromGecko(newColor));
|
||||
}
|
||||
|
||||
// Parses a color from an RGB triple of the form "rgb([0-9]+, [0-9]+, [0-9]+)". If the color
|
||||
// cannot be parsed, returns white.
|
||||
private static int parseColorFromGecko(String string) {
|
||||
if (sColorPattern == null) {
|
||||
sColorPattern = Pattern.compile("rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)");
|
||||
}
|
||||
|
||||
Matcher matcher = sColorPattern.matcher(string);
|
||||
if (!matcher.matches()) {
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
int r = Integer.parseInt(matcher.group(1));
|
||||
int g = Integer.parseInt(matcher.group(2));
|
||||
int b = Integer.parseInt(matcher.group(3));
|
||||
return Color.rgb(r, g, b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 160 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 82 B |
After Width: | Height: | Size: 264 B |
After Width: | Height: | Size: 181 B |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 133 B After Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 140 B After Width: | Height: | Size: 142 B |
@ -16,10 +16,10 @@
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<ImageView android:layout_width="43dip"
|
||||
android:layout_height="15dip"
|
||||
<ImageView android:layout_width="44dip"
|
||||
android:layout_height="16dip"
|
||||
android:layout_marginLeft="4dip"
|
||||
android:layout_marginTop="10dip"
|
||||
android:layout_marginTop="9dip"
|
||||
android:layout_alignParentTop="true"
|
||||
android:src="@drawable/doorhanger_arrow"
|
||||
android:scaleType="fitXY"/>
|
||||
|
@ -1560,6 +1560,7 @@ Tab.prototype = {
|
||||
|
||||
let frameLoader = this.browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
|
||||
frameLoader.renderMode = Ci.nsIFrameLoader.RENDER_MODE_ASYNC_SCROLL;
|
||||
frameLoader.clampScrollPosition = false;
|
||||
|
||||
// only set tab uri if uri is valid
|
||||
let uri = null;
|
||||
@ -1725,10 +1726,8 @@ Tab.prototype = {
|
||||
let x = aViewport.x / aViewport.zoom;
|
||||
let y = aViewport.y / aViewport.zoom;
|
||||
|
||||
// Set scroll-port size and scroll position (both in CSS pixels)
|
||||
// Set scroll position
|
||||
let win = this.browser.contentWindow;
|
||||
win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).setScrollPositionClampingScrollPortSize(
|
||||
gScreenWidth / aViewport.zoom, gScreenHeight / aViewport.zoom);
|
||||
win.scrollTo(x, y);
|
||||
this.userScrollPos.x = win.scrollX;
|
||||
this.userScrollPos.y = win.scrollY;
|
||||
@ -2044,11 +2043,6 @@ Tab.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
let browser = BrowserApp.getBrowserForWindow(aWebProgress.DOMWindow);
|
||||
let uri = "";
|
||||
if (browser)
|
||||
uri = browser.currentURI.spec;
|
||||
|
||||
// Check to see if we restoring the content from a previous presentation (session)
|
||||
// since there should be no real network activity
|
||||
let restoring = aStateFlags & Ci.nsIWebProgressListener.STATE_RESTORING;
|
||||
@ -2056,6 +2050,10 @@ Tab.prototype = {
|
||||
|
||||
// true if the page loaded successfully (i.e., no 404s or other errors)
|
||||
let success = false;
|
||||
let uri = "";
|
||||
try {
|
||||
uri = aRequest.QueryInterface(Components.interfaces.nsIChannel).originalURI.spec;
|
||||
} catch (e) { }
|
||||
try {
|
||||
success = aRequest.QueryInterface(Components.interfaces.nsIHttpChannel).requestSucceeded;
|
||||
} catch (e) { }
|
||||
|