Merge last green PGO from inbound to central

This commit is contained in:
Marco Bonardo 2012-03-10 11:21:28 +01:00
Родитель a0abfd7031 d3e8819329
Коммит 96d37c9159
450 изменённых файлов: 26202 добавлений и 11387 удалений

Просмотреть файл

@ -571,3 +571,26 @@ interface nsIAccessibleTableChangeEvent: nsISupports
readonly attribute long numRowsOrCols;
};
/*
* An interface for virtual cursor changed events.
* Passes previous cursor position and text offsets.
*/
[scriptable, uuid(370e8b9b-2bbc-4bff-a9c7-16ddc54aea21)]
interface nsIAccessibleVirtualCursorChangeEvent : nsISupports
{
/**
* Previous object pointed at by virtual cursor. null if none.
*/
readonly attribute nsIAccessible oldAccessible;
/**
* Previous start offset of pivot. -1 if none.
*/
readonly attribute long oldStartOffset;
/**
* Previous end offset of pivot. -1 if none.
*/
readonly attribute long oldEndOffset;
};

Просмотреть файл

@ -380,3 +380,24 @@ AccTableChangeEvent::CreateXPCOMObject()
return event;
}
////////////////////////////////////////////////////////////////////////////////
// AccVCChangeEvent
////////////////////////////////////////////////////////////////////////////////
AccVCChangeEvent::
AccVCChangeEvent(nsAccessible* aAccessible,
nsIAccessible* aOldAccessible,
PRInt32 aOldStart, PRInt32 aOldEnd) :
AccEvent(::nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, aAccessible),
mOldAccessible(aOldAccessible), mOldStart(aOldStart), mOldEnd(aOldEnd)
{
}
already_AddRefed<nsAccEvent>
AccVCChangeEvent::CreateXPCOMObject()
{
nsAccEvent* event = new nsAccVirtualCursorChangeEvent(this);
NS_ADDREF(event);
return event;
}

Просмотреть файл

@ -129,7 +129,8 @@ public:
eShowEvent,
eCaretMoveEvent,
eSelectionChangeEvent,
eTableChangeEvent
eTableChangeEvent,
eVirtualCursorChangeEvent
};
static const EventGroup kEventGroup = eGenericEvent;
@ -399,6 +400,37 @@ private:
PRUint32 mNumRowsOrCols; // the number of inserted/deleted rows/columns
};
/**
* Accessible virtual cursor change event.
*/
class AccVCChangeEvent : public AccEvent
{
public:
AccVCChangeEvent(nsAccessible* aAccessible,
nsIAccessible* aOldAccessible,
PRInt32 aOldStart, PRInt32 aOldEnd);
virtual ~AccVCChangeEvent() { }
// AccEvent
virtual already_AddRefed<nsAccEvent> CreateXPCOMObject();
static const EventGroup kEventGroup = eVirtualCursorChangeEvent;
virtual unsigned int GetEventGroups() const
{
return AccEvent::GetEventGroups() | (1U << eVirtualCursorChangeEvent);
}
// AccTableChangeEvent
nsIAccessible* OldAccessible() const { return mOldAccessible; }
PRInt32 OldStartOffset() const { return mOldStart; }
PRInt32 OldEndOffset() const { return mOldEnd; }
private:
nsRefPtr<nsIAccessible> mOldAccessible;
PRInt32 mOldStart;
PRInt32 mOldEnd;
};
/**
* Downcast the generic accessible event object to derived type.

Просмотреть файл

@ -1450,6 +1450,23 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
if (!mContent->IsElement())
return NS_OK;
// Expose draggable object attribute?
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
if (htmlElement) {
bool draggable = false;
htmlElement->GetDraggable(&draggable);
if (draggable) {
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
NS_LITERAL_STRING("true"));
}
}
// Don't calculate CSS-based object attributes when no frame (i.e.
// the accessible is not unattached form three) or when the accessible is not
// primary for node (like list bullet or XUL tree items).
if (!mContent->GetPrimaryFrame() || !IsPrimaryForNode())
return NS_OK;
// CSS style based object attributes.
nsAutoString value;
StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
@ -1482,17 +1499,6 @@ nsAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
styleInfo.MarginBottom(value);
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::marginBottom, value);
// Expose draggable object attribute?
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(mContent);
if (htmlElement) {
bool draggable = false;
htmlElement->GetDraggable(&draggable);
if (draggable) {
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::draggable,
NS_LITERAL_STRING("true"));
}
}
return NS_OK;
}

Просмотреть файл

@ -923,7 +923,8 @@ nsDocAccessible::OnPivotChanged(nsIAccessiblePivot* aPivot,
nsIAccessible* aOldAccessible,
PRInt32 aOldStart, PRInt32 aOldEnd)
{
nsRefPtr<AccEvent> event = new AccEvent(nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED, this);
nsRefPtr<AccEvent> event = new AccVCChangeEvent(this, aOldAccessible,
aOldStart, aOldEnd);
nsEventShell::FireEvent(event);
return NS_OK;

Просмотреть файл

@ -253,3 +253,40 @@ nsAccTableChangeEvent::GetNumRowsOrCols(PRInt32* aNumRowsOrCols)
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsAccVirtualCursorChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccVirtualCursorChangeEvent, nsAccEvent,
nsIAccessibleVirtualCursorChangeEvent)
NS_IMETHODIMP
nsAccVirtualCursorChangeEvent::GetOldAccessible(nsIAccessible** aOldAccessible)
{
NS_ENSURE_ARG_POINTER(aOldAccessible);
*aOldAccessible =
static_cast<AccVCChangeEvent*>(mEvent.get())->OldAccessible();
NS_IF_ADDREF(*aOldAccessible);
return NS_OK;
}
NS_IMETHODIMP
nsAccVirtualCursorChangeEvent::GetOldStartOffset(PRInt32* aOldStartOffset)
{
NS_ENSURE_ARG_POINTER(aOldStartOffset);
*aOldStartOffset =
static_cast<AccVCChangeEvent*>(mEvent.get())->OldStartOffset();
return NS_OK;
}
NS_IMETHODIMP
nsAccVirtualCursorChangeEvent::GetOldEndOffset(PRInt32* aOldEndOffset)
{
NS_ENSURE_ARG_POINTER(aOldEndOffset);
*aOldEndOffset =
static_cast<AccVCChangeEvent*>(mEvent.get())->OldEndOffset();
return NS_OK;
}

Просмотреть файл

@ -164,5 +164,25 @@ private:
nsAccTableChangeEvent& operator =(const nsAccTableChangeEvent&);
};
/**
* Accessible virtual cursor change event.
*/
class nsAccVirtualCursorChangeEvent : public nsAccEvent,
public nsIAccessibleVirtualCursorChangeEvent
{
public:
nsAccVirtualCursorChangeEvent(AccVCChangeEvent* aEvent) :
nsAccEvent(aEvent) { }
virtual ~nsAccVirtualCursorChangeEvent() { }
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLEVIRTUALCURSORCHANGEEVENT
private:
nsAccVirtualCursorChangeEvent() MOZ_DELETE;
nsAccVirtualCursorChangeEvent(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
nsAccVirtualCursorChangeEvent& operator =(const nsAccVirtualCursorChangeEvent&) MOZ_DELETE;
};
#endif

Просмотреть файл

@ -47,6 +47,23 @@ function testCSSAttrs(aID)
testAttrs(aID, attrs, true);
}
/**
* Test the accessible that it doesn't have CSS-based object attributes.
*/
function testAbsentCSSAttrs(aID)
{
var attrs = {
"display": "",
"text-align": "",
"text-indent": "",
"margin-left": "",
"margin-right": "",
"margin-top": "",
"margin-bottom": ""
};
testAbsentAttrs(aID, attrs);
}
/**
* Test group object attributes (posinset, setsize and level) and
* nsIAccessible::groupPosition() method.

Просмотреть файл

@ -82,6 +82,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
testCSSAttrs("tr");
testCSSAttrs("td");
// no CSS-based object attributes
testAbsentCSSAttrs(getAccessible("listitem").firstChild);
SimpleTest.finish();
}
@ -111,6 +114,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
title="Don't use GetComputedStyle for object attribute calculation">
Mozilla Bug 714579
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=729831"
title="Don't expose CSS-based object attributes on not in tree accessible and accessible having no DOM element">
Mozilla Bug 729831
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -189,5 +197,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=689540
<td id="td">td</td>
</tr>
</table>
<ul>
<li id="listitem">item
</ul>
</body>
</html>

Просмотреть файл

@ -10,6 +10,8 @@ const nsIAccessibleCaretMoveEvent =
Components.interfaces.nsIAccessibleCaretMoveEvent;
const nsIAccessibleTextChangeEvent =
Components.interfaces.nsIAccessibleTextChangeEvent;
const nsIAccessibleVirtualCursorChangeEvent =
Components.interfaces.nsIAccessibleVirtualCursorChangeEvent;
const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;

Просмотреть файл

@ -74,6 +74,15 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
this.check = function virtualCursorChangedChecker_check(aEvent)
{
SimpleTest.info("virtualCursorChangedChecker_check");
var event = null;
try {
event = aEvent.QueryInterface(nsIAccessibleVirtualCursorChangeEvent);
} catch (e) {
SimpleTest.ok(false, "Does not support correct interface: " + e);
}
var position = aDocAcc.virtualCursor.position;
var idMatches = position.DOMNode.id == aIdOrNameOrAcc;
@ -90,9 +99,38 @@ function virtualCursorChangedChecker(aDocAcc, aIdOrNameOrAcc, aTextOffsets)
SimpleTest.is(aDocAcc.virtualCursor.endOffset, aTextOffsets[1],
"wrong end offset");
}
var prevPosAndOffset = virtualCursorChangedChecker.
getPreviousPosAndOffset(aDocAcc.virtualCursor);
if (prevPosAndOffset) {
SimpleTest.is(event.oldAccessible, prevPosAndOffset.position,
"previous position does not match");
SimpleTest.is(event.oldStartOffset, prevPosAndOffset.startOffset,
"previous start offset does not match");
SimpleTest.is(event.oldEndOffset, prevPosAndOffset.endOffset,
"previous end offset does not match");
}
};
}
virtualCursorChangedChecker.prevPosAndOffset = {};
virtualCursorChangedChecker.storePreviousPosAndOffset =
function storePreviousPosAndOffset(aPivot)
{
virtualCursorChangedChecker.prevPosAndOffset[aPivot] =
{position: aPivot.position,
startOffset: aPivot.startOffset,
endOffset: aPivot.endOffset};
};
virtualCursorChangedChecker.getPreviousPosAndOffset =
function getPreviousPosAndOffset(aPivot)
{
return virtualCursorChangedChecker.prevPosAndOffset[aPivot];
};
/**
* Set a text range in the pivot and wait for virtual cursor change event.
*
@ -105,6 +143,8 @@ function setVirtualCursorRangeInvoker(aDocAcc, aTextAccessible, aTextOffsets)
{
this.invoke = function virtualCursorChangedInvoker_invoke()
{
virtualCursorChangedChecker.
storePreviousPosAndOffset(aDocAcc.virtualCursor);
SimpleTest.info(prettyName(aTextAccessible) + " " + aTextOffsets);
aDocAcc.virtualCursor.setTextRange(aTextAccessible,
aTextOffsets[0],
@ -136,6 +176,8 @@ function setVirtualCursorPosInvoker(aDocAcc, aPivotMoveMethod, aRule,
{
this.invoke = function virtualCursorChangedInvoker_invoke()
{
virtualCursorChangedChecker.
storePreviousPosAndOffset(aDocAcc.virtualCursor);
var moved = aDocAcc.virtualCursor[aPivotMoveMethod](aRule);
SimpleTest.ok((aIdOrNameOrAcc && moved) || (!aIdOrNameOrAcc && !moved),
"moved pivot");

Просмотреть файл

@ -64,6 +64,9 @@ XPCOMUtils.defineLazyGetter(this, "PlacesUtils", function() {
return PlacesUtils;
});
XPCOMUtils.defineLazyModuleGetter(this, "KeywordURLResetPrompter",
"resource:///modules/KeywordURLResetPrompter.jsm");
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
@ -277,6 +280,13 @@ BrowserGlue.prototype = {
this._initPlaces();
}
break;
case "defaultURIFixup-using-keyword-pref":
if (KeywordURLResetPrompter.shouldPrompt) {
let keywordURI = subject.QueryInterface(Ci.nsIURI);
KeywordURLResetPrompter.prompt(this.getMostRecentBrowserWindow(),
keywordURI);
}
break;
}
},
@ -306,6 +316,7 @@ BrowserGlue.prototype = {
os.addObserver(this, "distribution-customization-complete", false);
os.addObserver(this, "places-shutdown", false);
this._isPlacesShutdownObserver = true;
os.addObserver(this, "defaultURIFixup-using-keyword-pref", false);
},
// cleanup (called on application shutdown)
@ -334,6 +345,7 @@ BrowserGlue.prototype = {
os.removeObserver(this, "places-database-locked");
if (this._isPlacesShutdownObserver)
os.removeObserver(this, "places-shutdown");
os.removeObserver(this, "defaultURIFixup-using-keyword-pref");
},
_onAppDefaults: function BG__onAppDefaults() {

Просмотреть файл

@ -333,6 +333,22 @@ telemetryYesButtonLabel2 = Yes, I want to help
telemetryYesButtonAccessKey = Y
telemetryNoButtonLabel = No
telemetryNoButtonAccessKey = N
# Keyword.URL reset prompt
# LOCALIZATION NOTE (keywordPrompt.message):
# - %1$S is brandShortName
# - %2$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
# - %3$S is the name of the default search engine (e.g. "Google")
keywordPrompt.message = %1$S is using '%2$S' for searches from the location bar. Would you like to restore the default search (%3$S)?
# LOCALIZATION NOTE (keywordPrompt.yesButton): %1$S is the name of the default search engine
keywordPrompt.yesButton = Yes, use %1$S
keywordPrompt.yesButton.accessKey = Y
# LOCALIZATION NOTE (keywordPrompt.noButton): %1$S is a host name (e.g. "somewebsearch.com") from the current value of keyword.URL
keywordPrompt.noButton = No, continue using '%1$S'
keywordPrompt.noButton.accessKey = N
# Telemetry opt-out prompt for Aurora and Nightly
# LOCALIZATION NOTE (telemetryOptOutPrompt): %1$S and %3$S will be replaced by
# brandFullName, and %2$S by the value of the toolkit.telemetry.server_owner preference.

Просмотреть файл

@ -0,0 +1,105 @@
/* 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/. */
let EXPORTED_SYMBOLS = [ "KeywordURLResetPrompter" ];
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
const KEYWORD_PROMPT_REV = 1;
let KeywordURLResetPrompter = {
get shouldPrompt() {
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
let declinedRev;
try {
declinedRev = Services.prefs.getIntPref("browser.keywordURLPromptDeclined");
} catch (ex) {}
return keywordURLUserSet && declinedRev != KEYWORD_PROMPT_REV;
},
prompt: function KeywordURLResetPrompter_prompt(win, keywordURI) {
let tabbrowser = win.gBrowser;
let notifyBox = tabbrowser.getNotificationBox();
let existingNotification = notifyBox.getNotificationWithValue("keywordURL-reset");
if (existingNotification)
return;
// Find the name/URI of this build's original default engine.
// XXX: Can't use originalDefaultEngine getter here, because that doesn't
// use the default pref branch.
let defaultURI;
let defaultEngine;
try {
let defaultPB = Services.prefs.getDefaultBranch(null);
let defaultName = defaultPB.getComplexValue("browser.search.defaultenginename",
Ci.nsIPrefLocalizedString).data;
defaultEngine = Services.search.getEngineByName(defaultName);
defaultURI = defaultEngine.getSubmission("foo").uri;
} catch (ex) {
// Something went horribly wrong! bail out
return;
}
// If the user-set value has the same base domain as the default, don't
// prompt.
let keywordBaseDomain;
try {
keywordBaseDomain = Services.eTLD.getBaseDomain(keywordURI);
if (keywordBaseDomain == Services.eTLD.getBaseDomain(defaultURI))
return;
} catch (ex) {}
if (!keywordBaseDomain)
return;
let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
let brandShortName = brandBundle.GetStringFromName("brandShortName");
let browserBundle = win.gNavigatorBundle;
let msg = browserBundle.getFormattedString("keywordPrompt.message",
[brandShortName, keywordBaseDomain,
defaultEngine.name]);
let buttons = [
{
label: browserBundle.getFormattedString("keywordPrompt.yesButton",
[defaultEngine.name]),
accessKey: browserBundle.getString("keywordPrompt.yesButton.accessKey"),
popup: null,
callback: function(aNotificationBar, aButton) {
Services.prefs.clearUserPref("keyword.URL");
try {
// If the currently loaded URI still has the same base domain as the
// keyword URI (this is used as a rough approximation of whether the
// user is still seeing search results as opposed to having clicked
// on a result link), load the default engine's searchForm URL so
// that they can re-do their search.
let currentBaseDomain = Services.eTLD.getBaseDomain(tabbrowser.currentURI);
if (currentBaseDomain == keywordBaseDomain)
tabbrowser.loadURI(defaultEngine.searchForm);
} catch (ex) {}
}
},
{
label: browserBundle.getFormattedString("keywordPrompt.noButton",
[keywordBaseDomain]),
accessKey: browserBundle.getString("keywordPrompt.noButton.accessKey"),
popup: null,
callback: function(aNotificationBar, aButton) {
Services.prefs.setIntPref("browser.keywordURLPromptDeclined", KEYWORD_PROMPT_REV);
}
}
];
let notification = notifyBox.appendNotification(msg, "keywordURL-reset", null, notifyBox.PRIORITY_WARNING_HIGH, buttons);
notification.setAttribute("hideclose", true);
// stick around for a few page loads in case there are redirects involved
notification.persistence = 3;
}
}

Просмотреть файл

@ -52,6 +52,7 @@ EXTRA_JS_MODULES = \
NewTabUtils.jsm \
offlineAppCache.jsm \
TelemetryTimestamps.jsm \
KeywordURLResetPrompter.jsm \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.8 KiB

После

Ширина:  |  Высота:  |  Размер: 863 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.8 KiB

После

Ширина:  |  Высота:  |  Размер: 863 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.8 KiB

После

Ширина:  |  Высота:  |  Размер: 863 B

Просмотреть файл

@ -960,10 +960,10 @@ ifdef MSMANIFEST_TOOL
endif # MSVC with manifest tool
else
ifeq ($(CPP_PROG_LINK),1)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
@$(call CHECK_STDCXX,$@)
else
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
endif # CPP_PROG_LINK
endif # WINNT && !GNU_CC

Просмотреть файл

@ -5,7 +5,7 @@
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body>
<iframe name="submit_frame" onLoad="doCheck();"></iframe>
<iframe name="submit_frame"></iframe>
<form method="get" id="form1" target="submit_frame" action="../../../../../blah">
<input type="text" name="field1" value="teststring"><br>
<input type="radio" name="field2" value="0" checked> 0
@ -27,13 +27,16 @@
<input type="button" name="field13" value="button">
</form>
<script>
document.forms[0].submit();
SimpleTest.waitForExplicitFinish();
function doCheck(){
addLoadEvent(function() {
document.getElementsByName('submit_frame')[0].onload = function() {
is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=", "Submit string was correct.");
SimpleTest.finish();
}
};
document.forms[0].submit();
});
</script>
</body>
</html>

Просмотреть файл

@ -54,12 +54,14 @@
<script>
SimpleTest.waitForExplicitFinish();
frames['submit_frame'].onload = function() {
addLoadEvent(function() {
document.getElementsByName('submit_frame')[0].onload = function() {
is(frames['submit_frame'].location.href, "http://mochi.test:8888/blah?field1-2=teststring&field2-2=0&field4-2=1&field6-2=3&field7-2=2&field8-2=8&field9-2=9&field12-2=&field1=teststring&field2=0&field4=1&field6=3&field7=2&field8=8&field9=9&field12=&field14=14&field14-2=14", "Submit string was correct.");
SimpleTest.finish();
}
};
document.forms[0].submit();
});
</script>
</body>
</html>

Просмотреть файл

@ -54,6 +54,7 @@
#include "nsIURIFixup.h"
#include "nsDefaultURIFixup.h"
#include "mozilla/Preferences.h"
#include "nsIObserverService.h"
using namespace mozilla;
@ -378,7 +379,17 @@ NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
spec.Insert(url, 0);
return NS_NewURI(aURI, spec);
nsresult rv = NS_NewURI(aURI, spec);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
if (obsSvc) {
obsSvc->NotifyObservers(*aURI,
"defaultURIFixup-using-keyword-pref",
nsnull);
}
return NS_OK;
}
#ifdef MOZ_TOOLKIT_SEARCH

Просмотреть файл

@ -199,11 +199,14 @@ NS_IMETHODIMP nsDeviceMotion::RemoveListener(nsIDeviceMotionListener *aListener)
NS_IMETHODIMP nsDeviceMotion::AddWindowListener(nsIDOMWindow *aWindow)
{
if (mWindowListeners.IndexOf(aWindow) != NoIndex)
return NS_OK;
if (mStarted == false) {
mStarted = true;
Startup();
}
if (mWindowListeners.IndexOf(aWindow) == NoIndex)
mWindowListeners.AppendElement(aWindow);
return NS_OK;
}
@ -224,28 +227,34 @@ nsDeviceMotion::DeviceMotionChanged(PRUint32 type, double x, double y, double z)
if (!mEnabled)
return NS_ERROR_NOT_INITIALIZED;
for (PRUint32 i = mListeners.Count(); i > 0 ; ) {
nsCOMArray<nsIDeviceMotionListener> listeners = mListeners;
for (PRUint32 i = listeners.Count(); i > 0 ; ) {
--i;
nsRefPtr<nsDeviceMotionData> a = new nsDeviceMotionData(type, x, y, z);
mListeners[i]->OnMotionChange(a);
listeners[i]->OnMotionChange(a);
}
for (PRUint32 i = mWindowListeners.Length(); i > 0 ; ) {
nsCOMArray<nsIDOMWindow> windowListeners;
for (PRUint32 i = windowListeners.Count(); i > 0 ; ) {
windowListeners.AppendObject(mWindowListeners[i]);
}
for (PRUint32 i = windowListeners.Count(); i > 0 ; ) {
--i;
// check to see if this window is in the background. if
// it is, don't send any device motion to it.
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(mWindowListeners[i]);
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(windowListeners[i]);
if (!pwindow ||
!pwindow->GetOuterWindow() ||
pwindow->GetOuterWindow()->IsBackground())
continue;
nsCOMPtr<nsIDOMDocument> domdoc;
mWindowListeners[i]->GetDocument(getter_AddRefs(domdoc));
windowListeners[i]->GetDocument(getter_AddRefs(domdoc));
if (domdoc) {
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(mWindowListeners[i]);
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(windowListeners[i]);
if (type == nsIDeviceMotionData::TYPE_ACCELERATION)
FireDOMMotionEvent(domdoc, target, x, y, z);
else if (type == nsIDeviceMotionData::TYPE_ORIENTATION)

Просмотреть файл

@ -0,0 +1,32 @@
diff --git a/gfx/skia/include/core/SkPostConfig.h b/gfx/skia/include/core/SkPostConfig.h
--- a/gfx/skia/include/core/SkPostConfig.h
+++ b/gfx/skia/include/core/SkPostConfig.h
@@ -277,19 +277,28 @@
#endif
//////////////////////////////////////////////////////////////////////
#ifndef SK_OVERRIDE
#if defined(_MSC_VER)
#define SK_OVERRIDE override
#elif defined(__clang__)
+#if __has_feature(cxx_override_control)
// Some documentation suggests we should be using __attribute__((override)),
// but it doesn't work.
#define SK_OVERRIDE override
+#elif defined(__has_extension)
+#if __has_extension(cxx_override_control)
+#define SK_OVERRIDE override
+#endif
+#endif
+#ifndef SK_OVERRIDE
+#define SK_OVERRIDE
+#endif
#else
// Linux GCC ignores "__attribute__((override))" and rejects "override".
#define SK_OVERRIDE
#endif
#endif
//////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -282,9 +282,18 @@
#if defined(_MSC_VER)
#define SK_OVERRIDE override
#elif defined(__clang__)
#if __has_feature(cxx_override_control)
// Some documentation suggests we should be using __attribute__((override)),
// but it doesn't work.
#define SK_OVERRIDE override
#elif defined(__has_extension)
#if __has_extension(cxx_override_control)
#define SK_OVERRIDE override
#endif
#endif
#ifndef SK_OVERRIDE
#define SK_OVERRIDE
#endif
#else
// Linux GCC ignores "__attribute__((override))" and rejects "override".
#define SK_OVERRIDE

Просмотреть файл

@ -112,3 +112,5 @@ patch -p3 < uninitialized-margin.patch
patch -p3 < fix-comma-end-enum-list.patch
# Bug 719872 - Fix crash on Android by reverting to older FontHost impl
patch -p3 < old-android-fonthost.patch
# Bug 731384 - Fix compile errors on older versions of clang
patch -p3 < SkPostConfig.patch

Просмотреть файл

@ -0,0 +1,16 @@
// Tests conversion from gb18030 to Unicode
// This is a sniff test which doesn't cover the full gb18030 range: the test string
// includes only the ASCII range and the first 63 double byte characters
// and border values of 4 byte characters
load('CharsetConversionTests.js');
const inString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x81@\x81A\x81B\x81C\x81D\x81E\x81F\x81G\x81H\x81I\x81J\x81K\x81L\x81M\x81N\x81O\x81P\x81Q\x81R\x81S\x81T\x81U\x81V\x81W\x81X\x81Y\x81Z\x81[\x81\\\x81]\x81^\x81_\x81`\x81a\x81b\x81c\x81d\x81e\x81f\x81g\x81h\x81i\x81j\x81k\x81l\x81m\x81n\x81o\x81p\x81q\x81r\x81s\x81t\x81u\x81v\x81w\x81x\x81y\x81z\x81{\x81|\x81}\x81~\x810\x810\x841\xa46\x841\xa47\x849\xfe9\x850\x810\x859\xfe9\x860\x810\x8f9\xfe9\x900\x810\xe32\x9a5\xe32\x9a6\xe39\xfe9\xe40\x810\xfc9\xfe9\xfd0\x810\xfe9\xfe9";
const expectedString = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u4E02\u4E04\u4E05\u4E06\u4E0F\u4E12\u4E17\u4E1F\u4E20\u4E21\u4E23\u4E26\u4E29\u4E2E\u4E2F\u4E31\u4E33\u4E35\u4E37\u4E3C\u4E40\u4E41\u4E42\u4E44\u4E46\u4E4A\u4E51\u4E55\u4E57\u4E5A\u4E5B\u4E62\u4E63\u4E64\u4E65\u4E67\u4E68\u4E6A\u4E6B\u4E6C\u4E6D\u4E6E\u4E6F\u4E72\u4E74\u4E75\u4E76\u4E77\u4E78\u4E79\u4E7A\u4E7B\u4E7C\u4E7D\u4E7F\u4E80\u4E81\u4E82\u4E83\u4E84\u4E85\u4E87\u4E8A\x80\uFFFC\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uD800\uDC00\uDBFF\uDFFF\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD";
const aliases = [ "gb18030" ];
function run_test() {
testDecodeAliases();
}

Просмотреть файл

@ -63,6 +63,7 @@ tail =
[test_decode_CP874.js]
[test_decode_EUCKR_Hangul.js]
[test_decode_armscii.js]
[test_decode_gb18030.js]
[test_decode_gbk.js]
[test_decode_tcvn5712.js]
[test_decode_utf-7_internal.js]

Просмотреть файл

@ -298,8 +298,11 @@ bool nsGB18030ToUnicode::DecodeToSurrogate(const char* aSrc, PRUnichar* aOut)
a3 -= (PRUint8)0x81;
a4 -= (PRUint8)0x30;
PRUint32 idx = (((a1 * 10 + a2 ) * 126 + a3) * 10) + a4;
// idx == ucs4Codepoint - 0x10000
if (idx > 0x000FFFFF)
return false;
*aOut++ = 0xD800 | (0x000003FF & (idx >> 10));
*aOut++ = 0xD800 | (idx >> 10);
*aOut = 0xDC00 | (0x000003FF & idx);
return true;

Просмотреть файл

@ -960,10 +960,10 @@ ifdef MSMANIFEST_TOOL
endif # MSVC with manifest tool
else
ifeq ($(CPP_PROG_LINK),1)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
$(EXPAND_CCC) $(CXXFLAGS) -o $@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
@$(call CHECK_STDCXX,$@)
else
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
$(EXPAND_CC) $(CFLAGS) $(OUTOPTION)$@ $< $(WIN32_EXE_LDFLAGS) $(LDFLAGS) $(WRAP_LDFLAGS) $(LIBS_DIR) $(LIBS) $(MOZ_GLUE_PROGRAM_LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS) $(BIN_FLAGS)
endif # CPP_PROG_LINK
endif # WINNT && !GNU_CC

Просмотреть файл

@ -0,0 +1,4 @@
// In a debugger with no debuggees, findScripts should return no scripts.
var dbg = new Debugger;
assertEq(dbg.findScripts().length, 0);

Просмотреть файл

@ -0,0 +1,15 @@
// In a debuggee with functions, findScripts finds those functions' scripts.
var g = newGlobal('new-compartment');
g.eval('function f(){}');
g.eval('function g(){}');
g.eval('function h(){}');
var dbg = new Debugger(g);
var fw = dbg.addDebuggee(g.f);
var gw = dbg.addDebuggee(g.g);
var hw = dbg.addDebuggee(g.h);
assertEq(dbg.findScripts().indexOf(fw.script) != -1, true);
assertEq(dbg.findScripts().indexOf(gw.script) != -1, true);
assertEq(dbg.findScripts().indexOf(hw.script) != -1, true);

Просмотреть файл

@ -0,0 +1,16 @@
// While eval code is running, findScripts returns its script.
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var log;
g.check = function () {
log += 'c';
var frame = dbg.getNewestFrame();
assertEq(frame.type, "eval");
assertEq(dbg.findScripts().indexOf(frame.script) != -1, true);
};
log = '';
g.eval('check()');
assertEq(log, 'c');

Просмотреть файл

@ -0,0 +1,27 @@
// Within a series of evals and calls, all their frames' scripts appear in findScripts' result.
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var log;
g.check = function () {
log += 'c';
var scripts = dbg.findScripts();
var innerEvalFrame = dbg.getNewestFrame();
assertEq(innerEvalFrame.type, "eval");
assertEq(scripts.indexOf(innerEvalFrame.script) != -1, true);
var callFrame = innerEvalFrame.older;
assertEq(callFrame.type, "call");
assertEq(scripts.indexOf(callFrame.script) != -1, true);
var outerEvalFrame = callFrame.older;
assertEq(outerEvalFrame.type, "eval");
assertEq(scripts.indexOf(outerEvalFrame.script) != -1, true);
assertEq(innerEvalFrame != outerEvalFrame, true);
};
g.eval('function f() { eval("check();") }');
log = '';
g.eval('f();');
assertEq(log, 'c');

Просмотреть файл

@ -0,0 +1,17 @@
// findScripts' result includes scripts for nested functions.
var g = newGlobal('new-compartment');
var dbg = new Debugger(g);
var log;
g.eval('function f() { return function g() { return function h() { return "Squee!"; } } }');
var fw = dbg.addDebuggee(g.f);
var gw = dbg.addDebuggee(g.f());
var hw = dbg.addDebuggee(g.f()());
assertEq(fw.script != gw.script, true);
assertEq(fw.script != hw.script, true);
var scripts = dbg.findScripts();
assertEq(scripts.indexOf(fw.script) != -1, true);
assertEq(scripts.indexOf(gw.script) != -1, true);
assertEq(scripts.indexOf(hw.script) != -1, true);

Просмотреть файл

@ -0,0 +1,11 @@
// In a debugger with multiple debuggees, findScripts finds scripts across all debuggees.
var g1 = newGlobal('new-compartment');
var g2 = newGlobal('new-compartment');
var dbg = new Debugger(g1, g2);
g1.eval('function f() {}');
g2.eval('function g() {}');
var scripts = dbg.findScripts();
assertEq(scripts.indexOf(dbg.addDebuggee(g1.f).script) != -1, true);
assertEq(scripts.indexOf(dbg.addDebuggee(g2.g).script) != -1, true);

Просмотреть файл

@ -0,0 +1,81 @@
#include "tests.h"
JSBool
OperationCallback(JSContext *cx)
{
return false;
}
static unsigned sRemain;
JSBool
TriggerOperationCallback(JSContext *cx, unsigned argc, jsval *vp)
{
if (!sRemain--)
JS_TriggerOperationCallback(JS_GetRuntime(cx));
*vp = JSVAL_VOID;
return true;
}
BEGIN_TEST(testSlowScript)
{
JS_SetOperationCallback(cx, OperationCallback);
JS_DefineFunction(cx, global, "triggerOperationCallback", TriggerOperationCallback, 0, 0);
test("while (true)"
" for (i in [0,0,0,0])"
" triggerOperationCallback();");
test("while (true)"
" for (i in [0,0,0,0])"
" for (j in [0,0,0,0])"
" triggerOperationCallback();");
test("while (true)"
" for (i in [0,0,0,0])"
" for (j in [0,0,0,0])"
" for (k in [0,0,0,0])"
" triggerOperationCallback();");
test("function f() { while (true) yield triggerOperationCallback() }"
"for (i in f()) ;");
test("function f() { while (true) yield 1 }"
"for (i in f())"
" triggerOperationCallback();");
test("(function() {"
" while (true)"
" let (x = 1) { eval('triggerOperationCallback()'); }"
"})()");
return true;
}
bool
test(const char *bytes)
{
jsval v;
JS_SetOptions(cx, JS_GetOptions(cx) & ~(JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS));
sRemain = 0;
CHECK(!evaluate(bytes, __FILE__, __LINE__, &v));
CHECK(!JS_IsExceptionPending(cx));
sRemain = 1000;
CHECK(!evaluate(bytes, __FILE__, __LINE__, &v));
CHECK(!JS_IsExceptionPending(cx));
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_METHODJIT | JSOPTION_METHODJIT_ALWAYS);
sRemain = 0;
CHECK(!evaluate(bytes, __FILE__, __LINE__, &v));
CHECK(!JS_IsExceptionPending(cx));
sRemain = 1000;
CHECK(!evaluate(bytes, __FILE__, __LINE__, &v));
CHECK(!JS_IsExceptionPending(cx));
return true;
}
END_TEST(testSlowScript)

Просмотреть файл

@ -861,7 +861,8 @@ class JS_PUBLIC_API(AutoGCRooter) {
DESCRIPTOR = -13, /* js::AutoPropertyDescriptorRooter */
STRING = -14, /* js::AutoStringRooter */
IDVECTOR = -15, /* js::AutoIdVector */
OBJVECTOR = -16 /* js::AutoObjectVector */
OBJVECTOR = -16, /* js::AutoObjectVector */
SCRIPTVECTOR =-17 /* js::AutoScriptVector */
};
private:
@ -1139,6 +1140,19 @@ class AutoIdVector : public AutoVectorRooter<jsid>
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class AutoScriptVector : public AutoVectorRooter<JSScript *>
{
public:
explicit AutoScriptVector(JSContext *cx
JS_GUARD_OBJECT_NOTIFIER_PARAM)
: AutoVectorRooter<JSScript *>(cx, SCRIPTVECTOR)
{
JS_GUARD_OBJECT_NOTIFIER_INIT;
}
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
};
} /* namespace JS */
/************************************************************************/

Просмотреть файл

@ -2293,6 +2293,13 @@ AutoGCRooter::trace(JSTracer *trc)
MarkValueRootRange(trc, array->length(), array->start(), "js::AutoValueArray");
return;
}
case SCRIPTVECTOR: {
AutoScriptVector::VectorImpl &vector = static_cast<AutoScriptVector *>(this)->vector;
for (size_t i = 0; i < vector.length(); i++)
MarkScriptRoot(trc, &vector[i], "AutoScriptVector element");
return;
}
}
JS_ASSERT(tag >= 0);

Просмотреть файл

@ -118,8 +118,8 @@ GetGCObjectFixedSlotsKind(size_t numFixedSlots)
static inline bool
IsBackgroundAllocKind(AllocKind kind)
{
JS_ASSERT(kind <= FINALIZE_OBJECT_LAST);
return kind % 2 == 1;
JS_ASSERT(kind <= FINALIZE_LAST);
return kind <= FINALIZE_OBJECT_LAST && kind % 2 == 1;
}
static inline AllocKind
@ -353,9 +353,13 @@ class CellIter : public CellIterImpl
: lists(&comp->arenas),
kind(kind)
{
#ifdef JS_THREADSAFE
JS_ASSERT(comp->arenas.doneBackgroundFinalize(kind));
#endif
/*
* We have a single-threaded runtime, so there's no need to protect
* against other threads iterating or allocating. However, we do have
* background finalization; make sure people aren't using CellIter to
* walk such allocation kinds.
*/
JS_ASSERT(!IsBackgroundAllocKind(kind));
if (lists->isSynchronizedFreeList(kind)) {
lists = NULL;
} else {

Просмотреть файл

@ -988,6 +988,79 @@ js::UnwindScope(JSContext *cx, uint32_t stackDepth)
}
}
void
js::UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs)
{
/* c.f. the regular (catchable) TryNoteIter loop in Interpret. */
for (TryNoteIter tni(regs); !tni.done(); ++tni) {
JSTryNote *tn = *tni;
if (tn->kind == JSTRY_ITER) {
Value *sp = regs.fp()->base() + tn->stackDepth;
UnwindIteratorForUncatchableException(cx, &sp[-1].toObject());
}
}
}
TryNoteIter::TryNoteIter(const FrameRegs &regs)
: regs(regs),
script(regs.fp()->script()),
pcOffset(regs.pc - script->main())
{
if (JSScript::isValidOffset(script->trynotesOffset)) {
tn = script->trynotes()->vector;
tnEnd = tn + script->trynotes()->length;
} else {
tn = tnEnd = NULL;
}
settle();
}
void
TryNoteIter::operator++()
{
++tn;
settle();
}
bool
TryNoteIter::done() const
{
return tn == tnEnd;
}
void
TryNoteIter::settle()
{
for (; tn != tnEnd; ++tn) {
/* If pc is out of range, try the next one. */
if (pcOffset - tn->start >= tn->length)
continue;
/*
* We have a note that covers the exception pc but we must check
* whether the interpreter has already executed the corresponding
* handler. This is possible when the executed bytecode implements
* break or return from inside a for-in loop.
*
* In this case the emitter generates additional [enditer] and [gosub]
* opcodes to close all outstanding iterators and execute the finally
* blocks. If such an [enditer] throws an exception, its pc can still
* be inside several nested for-in loops and try-finally statements
* even if we have already closed the corresponding iterators and
* invoked the finally blocks.
*
* To address this, we make [enditer] always decrease the stack even
* when its implementation throws an exception. Thus already executed
* [enditer] and [gosub] opcodes will have try notes with the stack
* depth exceeding the current one and this condition is what we use to
* filter them out.
*/
if (tn->stackDepth <= regs.sp - regs.fp()->base())
break;
}
}
/*
* Increment/decrement the value 'v'. The resulting value is stored in *slot.
* The result of the expression (taking into account prefix/postfix) is stored
@ -4157,14 +4230,7 @@ END_CASE(JSOP_ARRAYPUSH)
JS_ASSERT(&cx->regs() == &regs);
JS_ASSERT(uint32_t(regs.pc - script->code) < script->length);
if (!cx->isExceptionPending()) {
/* This is an error, not a catchable exception, quit the frame ASAP. */
interpReturnOK = false;
} else {
JSThrowHook handler;
JSTryNote *tn, *tnlimit;
uint32_t offset;
if (cx->isExceptionPending()) {
/* Restore atoms local in case we will resume. */
atoms = script->atoms;
@ -4173,8 +4239,7 @@ END_CASE(JSOP_ARRAYPUSH)
Value rval;
JSTrapStatus st = Debugger::onExceptionUnwind(cx, &rval);
if (st == JSTRAP_CONTINUE) {
handler = cx->runtime->debugHooks.throwHook;
if (handler)
if (JSThrowHook handler = cx->runtime->debugHooks.throwHook)
st = handler(cx, script, regs.pc, &rval, cx->runtime->debugHooks.throwHookData);
}
@ -4195,40 +4260,10 @@ END_CASE(JSOP_ARRAYPUSH)
CHECK_INTERRUPT_HANDLER();
}
/*
* Look for a try block in script that can catch this exception.
*/
if (!JSScript::isValidOffset(script->trynotesOffset))
goto no_catch;
for (TryNoteIter tni(regs); !tni.done(); ++tni) {
JSTryNote *tn = *tni;
offset = (uint32_t)(regs.pc - script->main());
tn = script->trynotes()->vector;
tnlimit = tn + script->trynotes()->length;
do {
if (offset - tn->start >= tn->length)
continue;
/*
* We have a note that covers the exception pc but we must check
* whether the interpreter has already executed the corresponding
* handler. This is possible when the executed bytecode
* implements break or return from inside a for-in loop.
*
* In this case the emitter generates additional [enditer] and
* [gosub] opcodes to close all outstanding iterators and execute
* the finally blocks. If such an [enditer] throws an exception,
* its pc can still be inside several nested for-in loops and
* try-finally statements even if we have already closed the
* corresponding iterators and invoked the finally blocks.
*
* To address this, we make [enditer] always decrease the stack
* even when its implementation throws an exception. Thus already
* executed [enditer] and [gosub] opcodes will have try notes
* with the stack depth exceeding the current one and this
* condition is what we use to filter them out.
*/
if (tn->stackDepth > regs.sp - regs.fp()->base())
continue;
UnwindScope(cx, tn->stackDepth);
/*
* Set pc to the first bytecode after the the try note to point
@ -4236,8 +4271,6 @@ END_CASE(JSOP_ARRAYPUSH)
* the for-in loop.
*/
regs.pc = (script)->main() + tn->start + tn->length;
UnwindScope(cx, tn->stackDepth);
regs.sp = regs.fp()->base() + tn->stackDepth;
switch (tn->kind) {
@ -4278,9 +4311,8 @@ END_CASE(JSOP_ARRAYPUSH)
goto error;
}
}
} while (++tn != tnlimit);
}
no_catch:
/*
* Propagate the exception or error to the caller unless the exception
* is an asynchronous return from a generator.
@ -4294,6 +4326,9 @@ END_CASE(JSOP_ARRAYPUSH)
regs.fp()->clearReturnValue();
}
#endif
} else {
UnwindForUncatchableException(cx, regs);
interpReturnOK = false;
}
forced_return:

Просмотреть файл

@ -328,12 +328,33 @@ class InterpreterFrames {
extern void
UnwindScope(JSContext *cx, uint32_t stackDepth);
/*
* Unwind for an uncatchable exception. This means not running finalizers, etc;
* just preserving the basic engine stack invariants.
*/
extern void
UnwindForUncatchableException(JSContext *cx, const FrameRegs &regs);
extern bool
OnUnknownMethod(JSContext *cx, JSObject *obj, Value idval, Value *vp);
extern bool
IsActiveWithOrBlock(JSContext *cx, JSObject &obj, uint32_t stackDepth);
class TryNoteIter
{
const FrameRegs &regs;
JSScript *script;
uint32_t pcOffset;
JSTryNote *tn, *tnEnd;
void settle();
public:
TryNoteIter(const FrameRegs &regs);
bool done() const;
void operator++();
JSTryNote *operator*() const { return tn; }
};
/************************************************************************/
/*

Просмотреть файл

@ -876,14 +876,12 @@ static JSBool
CloseGenerator(JSContext *cx, JSObject *genobj);
#endif
namespace js {
/*
* Call ToObject(v).__iterator__(keyonly) if ToObject(v).__iterator__ exists.
* Otherwise construct the default iterator.
*/
JSBool
ValueToIterator(JSContext *cx, unsigned flags, Value *vp)
js::ValueToIterator(JSContext *cx, unsigned flags, Value *vp)
{
/* JSITER_KEYVALUE must always come with JSITER_FOREACH */
JS_ASSERT_IF(flags & JSITER_KEYVALUE, flags & JSITER_FOREACH);
@ -922,7 +920,7 @@ ValueToIterator(JSContext *cx, unsigned flags, Value *vp)
}
bool
CloseIterator(JSContext *cx, JSObject *obj)
js::CloseIterator(JSContext *cx, JSObject *obj)
{
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
@ -953,7 +951,7 @@ CloseIterator(JSContext *cx, JSObject *obj)
}
bool
UnwindIteratorForException(JSContext *cx, JSObject *obj)
js::UnwindIteratorForException(JSContext *cx, JSObject *obj)
{
Value v = cx->getPendingException();
cx->clearPendingException();
@ -963,7 +961,17 @@ UnwindIteratorForException(JSContext *cx, JSObject *obj)
return true;
}
} // namespace js
void
js::UnwindIteratorForUncatchableException(JSContext *cx, JSObject *obj)
{
if (obj->isIterator()) {
NativeIterator *ni = obj->getNativeIterator();
if (ni->flags & JSITER_ENUMERATE) {
JS_ASSERT(cx->enumerators == obj);
cx->enumerators = ni->next;
}
}
}
/*
* Suppress enumeration of deleted properties. This function must be called

Просмотреть файл

@ -196,6 +196,9 @@ CloseIterator(JSContext *cx, JSObject *iterObj);
extern bool
UnwindIteratorForException(JSContext *cx, JSObject *obj);
extern void
UnwindIteratorForUncatchableException(JSContext *cx, JSObject *obj);
}
extern bool

Просмотреть файл

@ -78,37 +78,21 @@ FindExceptionHandler(JSContext *cx)
StackFrame *fp = cx->fp();
JSScript *script = fp->script();
top:
if (cx->isExceptionPending() && JSScript::isValidOffset(script->trynotesOffset)) {
// The PC is updated before every stub call, so we can use it here.
unsigned offset = cx->regs().pc - script->main();
if (!JSScript::isValidOffset(script->trynotesOffset))
return NULL;
JSTryNoteArray *tnarray = script->trynotes();
for (unsigned i = 0; i < tnarray->length; ++i) {
JSTryNote *tn = &tnarray->vector[i];
// The following if condition actually tests two separate conditions:
// (1) offset - tn->start >= tn->length
// means the PC is not in the range of this try note, so we
// should continue searching, after considering:
// (2) offset - tn->start == tn->length
// means the PC is at the first op of the exception handler
// for this try note. This happens when an exception is thrown
// during recording: the interpreter sets the PC to the handler
// and then exits. In this case, we are in fact at the right
// exception handler.
//
// Hypothetically, the op we are at might have thrown an
// exception, in which case this would not be the right handler.
// But the first ops of exception handlers generated by our
// bytecode compiler cannot throw, so this is not possible.
if (offset - tn->start > tn->length)
continue;
if (tn->stackDepth > cx->regs().sp - fp->base())
continue;
error:
if (cx->isExceptionPending()) {
for (TryNoteIter tni(cx->regs()); !tni.done(); ++tni) {
JSTryNote *tn = *tni;
UnwindScope(cx, tn->stackDepth);
/*
* Set pc to the first bytecode after the the try note to point
* to the beginning of catch or finally or to [enditer] closing
* the for-in loop.
*/
jsbytecode *pc = script->main() + tn->start + tn->length;
cx->regs().pc = pc;
cx->regs().sp = fp->base() + tn->stackDepth;
@ -154,10 +138,12 @@ top:
bool ok = UnwindIteratorForException(cx, &cx->regs().sp[-1].toObject());
cx->regs().sp -= 1;
if (!ok)
goto top;
goto error;
}
}
}
} else {
UnwindForUncatchableException(cx, cx->regs());
}
return NULL;

Просмотреть файл

@ -47,6 +47,7 @@
#include "jsobj.h"
#include "jswrapper.h"
#include "jsarrayinlines.h"
#include "jsgcinlines.h"
#include "jsinterpinlines.h"
#include "jsobjinlines.h"
#include "jsopcodeinlines.h"
@ -54,6 +55,7 @@
#include "frontend/BytecodeCompiler.h"
#include "frontend/BytecodeEmitter.h"
#include "methodjit/Retcon.h"
#include "js/Vector.h"
#include "vm/Stack-inl.h"
@ -2032,6 +2034,87 @@ Debugger::removeDebuggeeGlobal(JSContext *cx, GlobalObject *global,
debuggees.remove(global);
}
/* A set of JSCompartment pointers. */
typedef HashSet<JSCompartment *, DefaultHasher<JSCompartment *>, RuntimeAllocPolicy> CompartmentSet;
JSBool
Debugger::findScripts(JSContext *cx, unsigned argc, Value *vp)
{
THIS_DEBUGGER(cx, argc, vp, "findScripts", args, dbg);
CompartmentSet compartments(cx);
if (!compartments.init()) {
js_ReportOutOfMemory(cx);
return false;
}
/* Assemble the set of debuggee compartments. */
for (GlobalObjectSet::Range r = dbg->debuggees.all(); !r.empty(); r.popFront()) {
if (!compartments.put(r.front()->compartment())) {
js_ReportOutOfMemory(cx);
return false;
}
}
/*
* Accumulate the scripts in an AutoScriptVector, instead of creating
* the JS array as we go, because we mustn't allocate JS objects or GC
* while we use the CellIter.
*/
AutoScriptVector scripts(cx);
/* Search each compartment for debuggee scripts. */
for (CompartmentSet::Range r = compartments.all(); !r.empty(); r.popFront()) {
for (gc::CellIter i(r.front(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
GlobalObject *global = script->getGlobalObjectOrNull();
if (global && dbg->debuggees.has(global)) {
if (!scripts.append(script)) {
js_ReportOutOfMemory(cx);
return false;
}
}
}
}
/*
* Since eval scripts have no global, we need to find them via the call
* stack, where frame's scope tells us the global in use.
*/
for (FrameRegsIter fri(cx); !fri.done(); ++fri) {
if (fri.fp()->isEvalFrame() && dbg->debuggees.has(&fri.fp()->scopeChain().global())) {
JSScript *script = fri.fp()->script();
/*
* If eval scripts never have global objects set, then we don't need
* to check the existing script vector for duplicates, since we only
* include scripts with globals above.
*/
JS_ASSERT(!script->getGlobalObjectOrNull());
if (!scripts.append(script)) {
js_ReportOutOfMemory(cx);
return false;
}
}
}
JSObject *result = NewDenseAllocatedArray(cx, scripts.length(), NULL);
if (!result)
return false;
result->ensureDenseArrayInitializedLength(cx, 0, scripts.length());
for (size_t i = 0; i < scripts.length(); i++) {
JSObject *scriptObject = dbg->wrapScript(cx, scripts[i]);
if (!scriptObject)
return false;
result->setDenseArrayElement(i, ObjectValue(*scriptObject));
}
args.rval().setObject(*result);
return true;
}
JSPropertySpec Debugger::properties[] = {
JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
@ -2052,6 +2135,7 @@ JSFunctionSpec Debugger::methods[] = {
JS_FN("getDebuggees", Debugger::getDebuggees, 0, 0),
JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 1, 0),
JS_FN("findScripts", Debugger::findScripts, 1, 0),
JS_FS_END
};

Просмотреть файл

@ -200,6 +200,7 @@ class Debugger {
static JSBool getDebuggees(JSContext *cx, unsigned argc, Value *vp);
static JSBool getNewestFrame(JSContext *cx, unsigned argc, Value *vp);
static JSBool clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp);
static JSBool findScripts(JSContext *cx, unsigned argc, Value *vp);
static JSBool construct(JSContext *cx, unsigned argc, Value *vp);
static JSPropertySpec properties[];
static JSFunctionSpec methods[];

Просмотреть файл

@ -46,9 +46,9 @@
# each font. Do not include the Unicode table in this list.
%ifdef XP_WIN
font.mathfont-glyph-tables = STIXNonUnicode, STIXSizeOneSym, STIXSize1, MathJax_Main, Asana Math, Standard Symbols L, Symbol
font.mathfont-glyph-tables = MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, Asana Math, Standard Symbols L, Symbol
%else
font.mathfont-glyph-tables = STIXNonUnicode, STIXSizeOneSym, STIXSize1, MathJax_Main, Asana Math, Standard Symbols L
font.mathfont-glyph-tables = MathJax_Main, STIXNonUnicode, STIXSizeOneSym, STIXSize1, Asana Math, Standard Symbols L
%endif
# The ordered list of fonts with which to attempt to stretch MathML

Просмотреть файл

@ -54,7 +54,7 @@ math {
display: inline;
font-size: inherit;
font-style: normal;
font-family: STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
font-family: MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
text-rendering: optimizeLegibility;
-moz-float-edge: margin-box;
}
@ -156,13 +156,18 @@ math[display="inline"] {
*/
[mathvariant] { /* shared and same as [mathvariant="normal"] */
/* reset all font properties except those that affect the size */
font-family: MathJax_Main, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
font-style: normal;
font-variant: normal;
font-weight: normal;
}
[mathvariant="bold-fraktur"],
[mathvariant="bold-fraktur"] {
font-weight: bold;
font-family: MathJax_Fraktur, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
}
[mathvariant="bold-script"] {
font-weight: bold;
font-family: MathJax_Script, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
}
[mathvariant="bold"] {
font-weight: bold;
@ -175,23 +180,32 @@ math[display="inline"] {
font-style: italic;
}
[mathvariant="sans-serif"] {
font-family: sans-serif;
font-family: MathJax_SansSerif, sans-serif;
}
[mathvariant="bold-sans-serif"] {
font-weight: bold;
font-family: sans-serif;
font-family: MathJax_SansSerif, sans-serif;
}
[mathvariant="sans-serif-italic"] {
font-family: sans-serif;
font-family: MathJax_SansSerif, sans-serif;
font-style: italic;
}
[mathvariant="sans-serif-bold-italic"] {
font-family: sans-serif;
font-family: MathJax_SansSerif, sans-serif;
font-weight: bold;
font-style: italic;
}
[mathvariant="monospace"] {
font-family: monospace;
font-family: MathJax_Typewriter, monospace;
}
[mathvariant="double-struck"] {
font-family: MathJax_AMS, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
}
[mathvariant="script"] {
font-family: MathJax_Script, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
}
[mathvariant="fraktur"] {
font-style: MathJax_Fraktur, STIXGeneral, DejaVu Serif, DejaVu Sans, Cambria, Cambria Math, Times, Lucida Sans Unicode, OpenSymbol, Standard Symbols L, serif;
}
/**************************************************************************/

Просмотреть файл

@ -2,11 +2,16 @@
== Line length ==
The line limit is 80 characters, except that excessively long blocks of preprocessor directives may exceed this if it makes the code more readable (e.g. MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g. URLs) may exceed this as well. Wrap expressions after binary operators.
The line limit is 80 characters, except that excessively long blocks of
preprocessor directives may exceed this if it makes the code more readable (e.g.
MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g.
URLs) may exceed this as well. Wrap expressions after binary operators.
== Capitalization ==
Standalone functions, classes, structs, and template parameters are named InterCaps-style. Member functions and fields in classes and structs are named camelCaps-style.
Standalone functions, classes, structs, and template parameters are named
InterCaps-style. Member functions and fields in classes and structs are named
camelCaps-style.
== Indentation ==
@ -22,7 +27,8 @@ Surround binary operators with a single space on either side.
if (x == 2)
return 17;
When describing pointer types, the * shall be adjacent to the type name. (Same goes for references -- & goes by the type name.)
When describing pointer types, the * shall be adjacent to the type name. (Same
goes for references -- & goes by the type name.)
int
Foo(int* p)
@ -31,7 +37,8 @@ When describing pointer types, the * shall be adjacent to the type name. (Same
int& i = *p;
}
A corollary: don't mix declaration types by declaring a T and a T* (or a T**, &c.) in the same declaration.
A corollary: don't mix declaration types by declaring a T and a T* (or a T**,
&c.) in the same declaration.
T* foo, bar; // BAD
@ -44,7 +51,9 @@ Don't brace single statements.
for (size_t i = 0; i < 5; i++)
frob(i);
But do brace them if the statement (or condition(s) or any additional consequents, if the braces would be associated with an if statement) occupies multiple lines.
But do brace them if the statement (or condition(s) or any additional
consequents, if the braces would be associated with an if statement) occupies
multiple lines.
if (cond1 ||
cond2)
@ -68,11 +77,13 @@ But do brace them if the statement (or condition(s) or any additional consequent
action();
}
Braces in control flow go at the end of the line except when associated with an |if| or loop-head where the condition covers multiple lines
Braces in control flow go at the end of the line except when associated with an
|if| or loop-head where the condition covers multiple lines
== Classes and structs ==
Inside class and structure definitions, public/private consume one level of indentation.
Inside class and structure definitions, public/private consume one level of
indentation.
class Baz
{
@ -80,7 +91,8 @@ Inside class and structure definitions, public/private consume one level of inde
Baz() { }
};
The absence of public/private in structs in which all members are public still consumes a level.
The absence of public/private in structs in which all members are public still
consumes a level.
struct Foo
{
@ -108,11 +120,16 @@ Member initialization in constructors should be formatted as follows:
}
};
Fields should go first in the class so that the basic structure is all in one place, consistently.
Fields should go first in the class so that the basic structure is all in one
place, consistently.
Use the inline keyword to annotate functions defined inline in a header. (If the function is defined inline in the class, don't bother adding it redundantly.)
Use the inline keyword to annotate functions defined inline in a header. (If
the function is defined inline in the class, don't bother adding it
redundantly.)
Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and assignment operator from classes not intended to be copied or assigned to avoid mistakes.
Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and
assignment operator from classes not intended to be copied or assigned to avoid
mistakes.
class Funky
{
@ -124,9 +141,11 @@ Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and ass
void operator=(const Funky& other) MOZ_DELETE;
};
Include a blank line between sections of structs and classes with different access control.
Include a blank line between sections of structs and classes with different
access control.
The "get" prefix is used when a method is fallible. If it's infallible, don't use it.
The "get" prefix is used when a method is fallible. If it's infallible, don't
use it.
class String
{
@ -143,9 +162,12 @@ Capitalize template parameter names to distinguish them from fields.
{
};
Use single-letter names if it makes sense (T for an arbitrary type, K for key type, V for value type, &c.). Otherwise use InterCaps-style names.
Use single-letter names if it makes sense (T for an arbitrary type, K for key
type, V for value type, &c.). Otherwise use InterCaps-style names.
When declaring or defining a function, template<...> goes on one line, the return type and other specifiers go on another line, and the function name and argument list go on a third line.
When declaring or defining a function, template<...> goes on one line, the
return type and other specifiers go on another line, and the function name and
argument list go on a third line.
template<typename T>
inline bool
@ -155,30 +177,38 @@ When declaring or defining a function, template<...> goes on one line, the retur
== Namespaces ==
All C++ code shall be in the mozilla namespace, except that functionality only used to implement external-facing API should be in the mozilla::detail namespace, indicating that it should not be directly used.
All C++ code shall be in the mozilla namespace, except that functionality only
used to implement external-facing API should be in the mozilla::detail
namespace, indicating that it should not be directly used.
Namespace opening braces go on the same line as the namespace declaration. Namespace closing braces shall be commented. Namespace contents are not indented.
Namespace opening braces go on the same line as the namespace declaration.
Namespace closing braces shall be commented. Namespace contents are not
indented.
namespace mozilla {
...
} // namespace mozilla
Don't use |using| in a header unless it's confined to a class or method. Implementation files for out-of-line functionality may use |using|.
Don't use |using| in a header unless it's confined to a class or method.
Implementation files for out-of-line functionality may use |using|.
== #includes ==
Headers that include mfbt headers use a fully-qualified include path, even if full qualification is not strictly necessary.
Headers that include mfbt headers use a fully-qualified include path, even if
full qualification is not strictly necessary.
#include "mozilla/Assertions.h"
mfbt headers should be included first, alphabetically. Standard includes should follow, separated from mfbt includes by a blank line.
mfbt headers should be included first, alphabetically. Standard includes should
follow, separated from mfbt includes by a blank line.
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include <string.h>
If a header dependency is limited simply to the existence of a class, forward-declare it rather than #include that header.
If a header dependency is limited simply to the existence of a class,
forward-declare it rather than #include that header.
namespace mozilla {
@ -190,9 +220,12 @@ If a header dependency is limited simply to the existence of a class, forward-de
== Preprocessor ==
Include guards should be named by determining the fully-qualified include path, then substituting _ for / and . in it, and finally appending a trailing _. For example, "mozilla/Assertions.h" becomes mozilla_Assertions_h_.
Include guards should be named by determining the fully-qualified include path,
then substituting _ for / and . in it, and finally appending a trailing _. For
example, "mozilla/Assertions.h" becomes mozilla_Assertions_h_.
Nested preprocessor directives indent the directive name (but not the #) by two spaces.
Nested preprocessor directives indent the directive name (but not the #) by two
spaces.
#ifdef __clang__
# define FOO ...
@ -200,7 +233,8 @@ Nested preprocessor directives indent the directive name (but not the #) by two
# define FOO ...
#endif
Comments within nested preprocessor directives align with directive names at that nesting depth.
Comments within nested preprocessor directives align with directive names at
that nesting depth.
#if defined(__GNUC__)
/* gcc supports C++11 override syntax. */
@ -209,11 +243,17 @@ Comments within nested preprocessor directives align with directive names at tha
# define MOZ_OVERRIDE /* unsupported */
#endif
Feature-testing macros may be defined to nothing. Macros intended to be textually expanded should be defined to a comment indicating non-support, as above or as appropriate to the situation.
Feature-testing macros may be defined to nothing. Macros intended to be
textually expanded should be defined to a comment indicating non-support, as
above or as appropriate to the situation.
No particular preference is expressed between testing for a macro being defined using defined(...) and using #ifdef.
No particular preference is expressed between testing for a macro being defined
using defined(...) and using #ifdef.
When defining a macro with different expansions for different compilers, the top level of distinction should be the compiler, and the next nested level should be the compiler version. Clang seems likely to be around for awhile, so to reduce confusion test for it separately from gcc even when it's not strictly necessary.
When defining a macro with different expansions for different compilers, the top
level of distinction should be the compiler, and the next nested level should be
the compiler version. Clang seems likely to be around for awhile, so to reduce
confusion test for it separately from gcc even when it's not strictly necessary.
#if defined(__clang__)
#elif defined(__GNUC__)
@ -223,20 +263,28 @@ When defining a macro with different expansions for different compilers, the top
#elif defined(_MSC_VER)
#endif
But don't distinguish clang's feature support using version checks: use the __has_feature() and __has_extension() macros instead, because vendors may customize clang's version numbers.
But don't distinguish clang's feature support using version checks: use the
__has_feature() and __has_extension() macros instead, because vendors may
customize clang's version numbers.
Prefer inline functions to macros whenever possible.
== Comments ==
Header files shall have a short descriptive comment underneath license boilerplate indicating what functionality the file implements, to be picked up by MXR and displayed in directory listings. (But see bug 717196, which currently prevents MXR from doing this if the MPL2 boilerplate is used.)
Header files shall have a short descriptive comment underneath license
boilerplate indicating what functionality the file implements, to be picked up
by MXR and displayed in directory listings. (But see bug 717196, which
currently prevents MXR from doing this if the MPL2 boilerplate is used.)
Assertions.h:
...license boilerplate...
/* Implementations of runtime and static assertion macros for C and C++. */
Classes intended for public use shall have interface comments explaining their functionality from the user's perspective. These comments shall include examples of how the relevant functionality might be used. These interface comments use /** */ doxygen/Javadoc-style comments.
Classes intended for public use shall have interface comments explaining their
functionality from the user's perspective. These comments shall include
examples of how the relevant functionality might be used. These interface
comments use /** */ doxygen/Javadoc-style comments.
/**
* The Frobber class simplifies the process of frobbing.
@ -245,21 +293,38 @@ Classes intended for public use shall have interface comments explaining their f
{
};
Comments describing implementation details (tradeoffs considered, assumptions made, mathematical background, &c.) occur separately from interface comments so that users need not consider them. They should go inside the class definition or inside the appropriate method, depending on the specificity of the comment.
Comments describing implementation details (tradeoffs considered, assumptions
made, mathematical background, &c.) occur separately from interface comments so
that users need not consider them. They should go inside the class definition
or inside the appropriate method, depending on the specificity of the comment.
Headers which are intended to be C-compatible shall use only /**/-style comments. (Code examples nested inside documentation comments may use //-style comments.) Headers which are C++-compatible may also use //-style comments.
Headers which are intended to be C-compatible shall use only /**/-style
comments. (Code examples nested inside documentation comments may use //-style
comments.) Headers which are C++-compatible may also use //-style comments.
Non-interface comments that are /**/-style shall not also be doxygen-style.
Use Python-style ** to denote exponentiation inside comments, not ^ (which can be confused with C-style bitwise xor). If you're writing sufficiently complex math, feel free to descend into LaTeX math mode ;-) inside implementation comments if you need to. (But keep it out of interface comments, because most people probably haven't seen LaTeX.)
Use Python-style ** to denote exponentiation inside comments, not ^ (which can
be confused with C-style bitwise xor). If you're writing sufficiently complex
math, feel free to descend into LaTeX math mode ;-) inside implementation
comments if you need to. (But keep it out of interface comments, because most
people probably haven't seen LaTeX.)
== Miscellaneous ==
Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the block start/end as needed. The contents of these blocks should not be indented.
Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the
block start/end as needed. The contents of these blocks should not be indented.
Add new functionality to new headers unless an existing header makes sense. Err on the side of more headers rather than fewer, as this helps to minimize dependencies. Don't add anything to Util.h, which will be split into multiple headers at some point (bug 713082).
Add new functionality to new headers unless an existing header makes sense.
Err on the side of more headers rather than fewer, as this helps to minimize
dependencies. Don't add anything to Util.h, which will be split into multiple
headers at some point (bug 713082).
Don't use bool for argument types unless the method is a "set" or "enable"-style method where the method name and bool value together indicate the sense of its effect. Use well-named enums in all other places, so that the semantics of the argument are clear at a glance and do not require knowing how the method interprets that argument.
Don't use bool for argument types unless the method is a "set" or "enable"-style
method where the method name and bool value together indicate the sense of its
effect. Use well-named enums in all other places, so that the semantics of the
argument are clear at a glance and do not require knowing how the method
interprets that argument.
void
setVisible(bool visible); // true clearly means visible, false clearly not

Просмотреть файл

@ -717,18 +717,4 @@ public class AboutHomeContent extends ScrollView {
return false;
}
}
public static class LinkTextView extends TextView {
public LinkTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setText(CharSequence text, BufferType type) {
SpannableString content = new SpannableString(text + " \u00BB");
content.setSpan(new UnderlineSpan(), 0, text.length(), 0);
super.setText(content, BufferType.SPANNABLE);
}
}
}

Просмотреть файл

@ -160,6 +160,10 @@
android:theme="@style/Gecko.Translucent.TabsTray"
android:launchMode="singleTask"/>
<activity android:name="org.mozilla.gecko.RemoteTabs"
android:theme="@style/Gecko.Translucent.TabsTray"
android:launchMode="singleTask"/>
<activity android:name="org.mozilla.gecko.GeckoPreferences"
android:theme="@style/Gecko.TitleBar.Preferences"
android:label="@string/settings_title"

Просмотреть файл

@ -39,6 +39,7 @@
package @ANDROID_PACKAGE_NAME@;
import org.mozilla.gecko.GeckoApp;
import org.mozilla.gecko.GeckoAppShell;
public class App extends GeckoApp {
public String getPackageName() {
@ -50,17 +51,19 @@ public class App extends GeckoApp {
}
public String getDefaultUAString() {
return "Mozilla/5.0 (Android; Linux armv7l; rv:@MOZ_APP_VERSION@) Gecko/@UA_BUILDID@ Firefox/@MOZ_APP_VERSION@ Fennec/@MOZ_APP_VERSION@";
String deviceType = "Mobile";
if (GeckoAppShell.isTablet())
deviceType = "Tablet";
return "Mozilla/5.0 (Android; " + deviceType + "; rv:@MOZ_APP_VERSION@) Gecko/@MOZ_APP_VERSION@ Firefox/@MOZ_APP_VERSION@";
}
public String getUAStringForHost(String host) {
// With our standard UA String, we get a 200 response code and
// client-side redirect from t.co. This slight tweak gives us a
// 302 response code
// client-side redirect from t.co. This bot-like UA gives us a
// 301 response code
if ("t.co".equals(host))
return "Mozilla/5.0 (Android; Linux armv7l; rv:@MOZ_APP_VERSION@) Gecko/@UA_BUILDID@ Firefox Mobile/@MOZ_APP_VERSION@";
return "Redirector/@MOZ_APP_VERSION@ (Android; rv:@MOZ_APP_VERSION@)";
return getDefaultUAString();
}
};

Просмотреть файл

@ -850,7 +850,6 @@ abstract public class GeckoApp
void showTabs() {
Intent intent = new Intent(mAppContext, TabsTray.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
overridePendingTransition(R.anim.grow_fade_in, 0);
}
@ -2073,10 +2072,6 @@ abstract public class GeckoApp
mMainHandler.sendMessage(message);
}
// An Android framework bug can cause an IME crash when focus changes invalidate text
// selection offsets. A workaround is to reset selection when the activity resumes.
GeckoAppShell.resetIMESelection();
int newOrientation = getResources().getConfiguration().orientation;
if (mOrientation != newOrientation) {

Просмотреть файл

@ -365,6 +365,7 @@ public class GeckoAppShell
return;
loadMozGlue();
// the extract libs parameter is being removed in bug 732069
loadLibsSetup(context);
loadSQLiteLibsNative(apkName, false);
sSQLiteLibsLoaded = true;
}
@ -620,12 +621,6 @@ public class GeckoAppShell
mInputConnection.returnIMEQueryResult(result, selectionStart, selectionLength);
}
public static void resetIMESelection() {
if (mInputConnection != null) {
mInputConnection.resetSelection();
}
}
static void onXreExit() {
// mLaunchState can only be Launched or GeckoRunning at this point
GeckoApp.setLaunchState(GeckoApp.LaunchState.GeckoExiting);

Просмотреть файл

@ -184,15 +184,9 @@ public class GeckoInputConnection
String text = content.toString();
clampSelection();
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if (a < 0) a = 0;
if (b < 0) b = 0;
if (a > b) {
int tmp = a;
a = b;
b = tmp;
}
switch (id) {
case R.id.selectAll:
@ -239,17 +233,9 @@ public class GeckoInputConnection
extract.partialStartOffset = -1;
extract.partialEndOffset = -1;
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if (a > b) {
int tmp = a;
a = b;
b = tmp;
}
extract.selectionStart = a;
extract.selectionEnd = b;
clampSelection();
extract.selectionStart = Selection.getSelectionStart(content);
extract.selectionEnd = Selection.getSelectionEnd(content);
extract.startOffset = 0;
try {
@ -272,10 +258,80 @@ public class GeckoInputConnection
return super.setSelection(start, end);
}
@Override
public boolean deleteSurroundingText(int leftLength, int rightLength) {
clampSelection();
return super.deleteSurroundingText(leftLength, rightLength);
}
@Override
public int getCursorCapsMode(int reqModes) {
clampSelection();
return super.getCursorCapsMode(reqModes);
}
@Override
public CharSequence getTextBeforeCursor(int length, int flags) {
clampSelection();
return super.getTextBeforeCursor(length, flags);
}
@Override
public CharSequence getSelectedText(int flags) {
clampSelection();
return super.getSelectedText(flags);
}
@Override
public CharSequence getTextAfterCursor(int length, int flags) {
clampSelection();
return super.getTextAfterCursor(length, flags);
}
@Override
public boolean setComposingText(CharSequence text, int newCursorPosition) {
replaceText(text, newCursorPosition, true);
return true;
clampSelection();
return super.setComposingText(text, newCursorPosition);
}
// Android's BaseInputConnection.java is vulnerable to IndexOutOfBoundsExceptions because it
// does not adequately protect against stale indexes for selections exceeding the content length
// when the Editable content changes. We must clamp the indexes to be safe.
private void clampSelection() {
Editable content = getEditable();
if (content == null) {
return;
}
final int selectionStart = Selection.getSelectionStart(content);
final int selectionEnd = Selection.getSelectionEnd(content);
int a = clampContentIndex(content, selectionStart);
int b = clampContentIndex(content, selectionEnd);
if (a > b) {
int tmp = a;
a = b;
b = tmp;
}
if (a != selectionStart || b != selectionEnd) {
Log.e(LOGTAG, "CLAMPING BOGUS SELECTION (" + selectionStart + ", " + selectionEnd
+ "] -> (" + a + ", " + b + "]", new AssertionError());
setSelection(a, b);
}
}
private static int clampContentIndex(Editable content, int index) {
if (index < 0) {
index = 0;
} else {
final int contentLength = content.length();
if (index > contentLength) {
index = contentLength;
}
}
return index;
}
private void replaceText(CharSequence text, int newCursorPosition, boolean composing) {
@ -309,15 +365,9 @@ public class GeckoInputConnection
if (a != -1 && b != -1) {
removeComposingSpans(content);
} else {
clampSelection();
a = Selection.getSelectionStart(content);
b = Selection.getSelectionEnd(content);
if (a < 0) a = 0;
if (b < 0) b = 0;
if (b < a) {
int tmp = a;
a = b;
b = tmp;
}
}
if (composing) {
@ -468,8 +518,14 @@ public class GeckoInputConnection
int start, int end) {
if (!mBatchMode) {
final Editable content = getEditable();
start = clampContentIndex(content, start);
end = clampContentIndex(content, end);
clampSelection();
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
if (start != a || end != b) {
if (DEBUG) {
Log.d(LOGTAG, String.format(
@ -761,6 +817,7 @@ public class GeckoInputConnection
!mKeyListener.onKeyDown(v, mEditable, keyCode, event)) {
// Make sure selection in Gecko is up-to-date
final Editable content = getEditable();
clampSelection();
int a = Selection.getSelectionStart(content);
int b = Selection.getSelectionEnd(content);
GeckoAppShell.sendEventToGecko(
@ -969,18 +1026,6 @@ public class GeckoInputConnection
mEditable.setSpan(this, 0, contents.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
Selection.setSelection(mEditable, contents.length());
}
public void resetSelection() {
// An Android framework bug can cause a SpannableStringBuilder crash when focus changes
// invalidate text selection offsets. A workaround is to reset selection when the activity
// resumes. More info: https://code.google.com/p/android/issues/detail?id=5164
Editable content = getEditable();
if (content != null) {
Log.d(LOGTAG, "IME: resetSelection");
int length = content.length();
setSelection(length, length);
}
}
}
class DebugGeckoInputConnection extends GeckoInputConnection {

Просмотреть файл

@ -0,0 +1,25 @@
/* 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/. */
package org.mozilla.gecko;
import android.content.Context;
import android.util.AttributeSet;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.widget.TextView;
public class LinkTextView extends TextView {
public LinkTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setText(CharSequence text, BufferType type) {
SpannableString content = new SpannableString(text + " \u00BB");
content.setSpan(new UnderlineSpan(), 0, text.length(), 0);
super.setText(content, BufferType.SPANNABLE);
}
}

Просмотреть файл

@ -94,12 +94,14 @@ FENNEC_JAVA_FILES = \
GeckoThread.java \
GlobalHistory.java \
LinkPreference.java \
LinkTextView.java \
ProfileMigrator.java \
PromptService.java \
sqlite/ByteBufferInputStream.java \
sqlite/MatrixBlobCursor.java \
sqlite/SQLiteBridge.java \
sqlite/SQLiteBridgeException.java \
RemoteTabs.java \
SetupScreen.java \
SurfaceLockInfo.java \
Tab.java \
@ -245,6 +247,9 @@ RES_LAYOUT = \
res/layout/notification_progress_text.xml \
res/layout/site_setting_title.xml \
res/layout/setup_screen.xml \
res/layout/remote_tabs.xml \
res/layout/remote_tabs_child.xml \
res/layout/remote_tabs_group.xml \
res/layout/tabs_row.xml \
res/layout/tabs_tray.xml \
res/layout/list_item_header.xml \
@ -290,6 +295,7 @@ RES_ANIM = \
RES_DRAWABLE_NODPI = \
res/drawable-nodpi/abouthome_bg.png \
res/drawable-nodpi/abouthome_topsites_bg.png \
res/drawable-nodpi/background.png \
res/drawable-nodpi/tabs_tray_bg.png \
res/drawable-nodpi/tabs_tray_pressed_bg.png \
$(NULL)
@ -525,7 +531,6 @@ MOZ_ANDROID_DRAWABLES += \
mobile/android/base/resources/drawable/awesomebar_tab_press_selected.xml \
mobile/android/base/resources/drawable/awesomebar_tab_selected.xml \
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/gecko_actionbar_bg.xml \
mobile/android/base/resources/drawable/progress_spinner.xml \
@ -547,6 +552,7 @@ MOZ_ANDROID_DRAWABLES += \
mobile/android/base/resources/drawable/progress_spinner_16.png \
mobile/android/base/resources/drawable/progress_spinner_17.png \
mobile/android/base/resources/drawable/progress_spinner_18.png \
mobile/android/base/resources/drawable/remote_tabs_group_bg_repeat.xml \
mobile/android/base/resources/drawable/start.png \
mobile/android/base/resources/drawable/site_security_level.xml \
mobile/android/base/resources/drawable/tabs_button.xml \

Просмотреть файл

@ -0,0 +1,230 @@
/* 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/. */
package org.mozilla.gecko;
import java.util.ArrayList;
import java.util.HashMap;
import org.mozilla.gecko.db.BrowserContract.Clients;
import org.mozilla.gecko.db.BrowserContract.Tabs;
import org.mozilla.gecko.db.BrowserContract;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Intent;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ExpandableListView;
import android.widget.SimpleExpandableListAdapter;
import android.text.TextUtils;
import android.util.Log;
public class RemoteTabs extends Activity
implements ExpandableListView.OnGroupClickListener, ExpandableListView.OnChildClickListener {
private static final String LOGTAG = "GeckoRemoteTabs";
private static int sPreferredHeight;
private static int sChildItemHeight;
private static int sGroupItemHeight;
private static ExpandableListView mList;
private static ArrayList <HashMap <String, String>> mClientsList;
private static ArrayList <ArrayList <HashMap <String, String>>> mTabsList;
// 50 for child + 2 for divider
private static final int CHILD_ITEM_HEIGHT = 52;
// 30 for group + 2 for divider
private static final int GROUP_ITEM_HEIGHT = 32;
private static final String[] PROJECTION_COLUMNS = new String[] {
BrowserContract.Tabs.TITLE, // 0
BrowserContract.Tabs.URL, // 1
BrowserContract.Clients.GUID, // 2
BrowserContract.Clients.NAME // 3
};
private static final String[] CLIENT_KEY = new String[] { "name" };
private static final String[] TAB_KEY = new String[] { "title" };
private static final int[] CLIENT_RESOURCE = new int[] { R.id.client };
private static final int[] TAB_RESOURCE = new int[] { R.id.tab };
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.remote_tabs);
mList = (ExpandableListView) findViewById(R.id.list);
mList.setOnGroupClickListener(this);
mList.setOnChildClickListener(this);
LinearLayout container = (LinearLayout) findViewById(R.id.container);
container.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
finishActivity();
}
});
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
sChildItemHeight = (int) (CHILD_ITEM_HEIGHT * metrics.density);
sGroupItemHeight = (int) (GROUP_ITEM_HEIGHT * metrics.density);
sPreferredHeight = (int) (0.67 * metrics.heightPixels);
// Query the database for remote tabs in AsyncTask
(new QueryRemoteTabsTask()).execute();
}
@Override
public void onBackPressed() {
startActivity(new Intent(this, TabsTray.class));
overridePendingTransition(R.anim.grow_fade_in, 0);
finishActivity();
}
void finishActivity() {
finish();
overridePendingTransition(0, R.anim.shrink_fade_out);
}
@Override
public boolean onGroupClick(ExpandableListView parent, View view, int position, long id) {
// By default, the group collapses/expands. Consume the event.
return true;
}
@Override
public boolean onChildClick(ExpandableListView parent, View view, int groupPosition, int childPosition, long id) {
HashMap <String, String> tab = mTabsList.get(groupPosition).get(childPosition);
if (tab == null) {
finishActivity();
return true;
}
String url = tab.get("url");
JSONObject args = new JSONObject();
try {
args.put("url", url);
args.put("engine", null);
args.put("userEntered", false);
} catch (Exception e) {
Log.e(LOGTAG, "error building JSON arguments");
}
Log.i(LOGTAG, "Sending message to Gecko: " + SystemClock.uptimeMillis() + " - Tab:Add");
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Add", args.toString()));
finishActivity();
return true;
}
// Tabs List Container holds the ExpandableListView
public static class TabsListContainer extends LinearLayout {
public TabsListContainer(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
SimpleExpandableListAdapter adapter = (SimpleExpandableListAdapter) mList.getExpandableListAdapter();
if (adapter == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
int groupCount = adapter.getGroupCount();
int childrenHeight = groupCount * sGroupItemHeight;
for (int i = 0; i < groupCount; i++)
childrenHeight += adapter.getChildrenCount(i) * sChildItemHeight;
int restrictedHeightSpec = MeasureSpec.makeMeasureSpec(Math.min(childrenHeight, sPreferredHeight), MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, restrictedHeightSpec);
}
}
// AsyncTask to query the database
private class QueryRemoteTabsTask extends GeckoAsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... unused) {
mClientsList = new ArrayList <HashMap <String, String>>();
mTabsList = new ArrayList <ArrayList <HashMap <String, String>>>();
Cursor tabs = getContentResolver().query(BrowserContract.Tabs.CONTENT_URI,
PROJECTION_COLUMNS,
BrowserContract.Tabs.CLIENT_GUID + " IS NOT NULL",
null,
null);
if (tabs == null)
return null;
String oldGuid = null;
ArrayList <HashMap <String, String>> tabsForClient = null;
HashMap <String, String> client;
HashMap <String, String> tab;
try {
while (tabs.moveToNext()) {
String title = tabs.getString(0);
String url = tabs.getString(1);
String guid = tabs.getString(2);
String name = tabs.getString(3);
if (oldGuid == null || !TextUtils.equals(oldGuid, guid)) {
client = new HashMap <String, String>();
client.put("name", name);
mClientsList.add(client);
tabsForClient = new ArrayList <HashMap <String, String>>();
mTabsList.add(tabsForClient);
oldGuid = new String(guid);
}
tab = new HashMap<String, String>();
tab.put("title", TextUtils.isEmpty(title) ? url : title);
tab.put("url", url);
tabsForClient.add(tab);
}
} finally {
tabs.close();
}
return null;
}
@Override
protected void onPostExecute(Void unused) {
if (mClientsList.size() == 0) {
finishActivity();
return;
}
mList.setAdapter(new SimpleExpandableListAdapter(getApplicationContext(),
mClientsList,
R.layout.remote_tabs_group,
CLIENT_KEY,
CLIENT_RESOURCE,
mTabsList,
R.layout.remote_tabs_child,
TAB_KEY,
TAB_RESOURCE));
for (int i = 0; i < mClientsList.size(); i++) {
mList.expandGroup(i);
}
}
}
}

Просмотреть файл

@ -39,8 +39,14 @@ package org.mozilla.gecko;
import java.util.ArrayList;
import org.mozilla.gecko.db.BrowserContract.Clients;
import org.mozilla.gecko.db.BrowserContract;
import android.accounts.AccountManager;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Build;
@ -66,6 +72,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
private static int sAddTabHeight;
private static ListView mList;
private static TabsListContainer mListContainer;
private static LinkTextView mRemoteTabs;
private TabsAdapter mTabsAdapter;
private boolean mWaitingForClose;
@ -84,7 +91,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
mList = (ListView) findViewById(R.id.list);
mListContainer = (TabsListContainer) findViewById(R.id.list_container);
LinearLayout addTab = (LinearLayout) findViewById(R.id.add_tab);
ImageButton addTab = (ImageButton) findViewById(R.id.add_tab);
addTab.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
GeckoApp.mAppContext.addTab();
@ -92,6 +99,13 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
}
});
mRemoteTabs = (LinkTextView) findViewById(R.id.remote_tabs);
mRemoteTabs.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
showRemoteTabs();
}
});
LinearLayout container = (LinearLayout) findViewById(R.id.container);
container.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
@ -111,6 +125,11 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
tabs.registerOnTabsChangedListener(this);
tabs.refreshThumbnails();
onTabChanged(null, null);
// If sync is set up, query the database for remote clients
// Cleanup after Bug: 734211 is fixed
if (AccountManager.get(getApplicationContext()).getAccountsByType("org.mozilla.firefox_sync").length > 0)
(new QueryForRemoteClientsTask()).execute();
}
@Override
@ -157,6 +176,12 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Screenshot:Cancel",""));
}
void showRemoteTabs() {
startActivity(new Intent(this, RemoteTabs.class));
overridePendingTransition(R.anim.grow_fade_in, 0);
finishActivity();
}
// Tabs List Container holds the ListView and the New Tab button
public static class TabsListContainer extends LinearLayout {
public TabsListContainer(Context context, AttributeSet attrs) {
@ -186,6 +211,35 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
}
}
// AsyncTask to see if there is any remote tabs in the database
private class QueryForRemoteClientsTask extends GeckoAsyncTask<Void, Void, Boolean> {
@Override
protected Boolean doInBackground(Void... unused) {
Cursor clients = getContentResolver().query(BrowserContract.Clients.CONTENT_URI,
null,
null,
null,
null);
if (clients == null)
return false;
try {
return clients.moveToNext();
} finally {
clients.close();
}
}
@Override
protected void onPostExecute(Boolean clientsExist) {
if (clientsExist.booleanValue())
mRemoteTabs.setVisibility(View.VISIBLE);
else
mRemoteTabs.setVisibility(View.GONE);
}
}
// Adapter to bind tabs into a list
private class TabsAdapter extends BaseAdapter {
public TabsAdapter(Context context, ArrayList<Tab> tabs) {

Просмотреть файл

@ -51,7 +51,7 @@ public class TabsProvider extends ContentProvider {
static final int CLIENTS = 602;
static final int CLIENTS_ID = 603;
static final String DEFAULT_TABS_SORT_ORDER = Tabs.POSITION + " ASC";
static final String DEFAULT_TABS_SORT_ORDER = Clients.LAST_MODIFIED + " DESC, " + Tabs.LAST_USED + " DESC";
static final String DEFAULT_CLIENTS_SORT_ORDER = Clients.LAST_MODIFIED + " DESC";
static final String INDEX_TABS_GUID = "tabs_guid_index";
@ -73,13 +73,15 @@ public class TabsProvider extends ContentProvider {
map = new HashMap<String, String>();
map.put(Tabs._ID, Tabs._ID);
map.put(Tabs.CLIENT_GUID, Tabs.CLIENT_GUID);
map.put(Tabs.TITLE, Tabs.TITLE);
map.put(Tabs.URL, Tabs.URL);
map.put(Tabs.HISTORY, Tabs.HISTORY);
map.put(Tabs.FAVICON, Tabs.FAVICON);
map.put(Tabs.LAST_USED, Tabs.LAST_USED);
map.put(Tabs.POSITION, Tabs.POSITION);
map.put(Clients.GUID, Clients.GUID);
map.put(Clients.NAME, Clients.NAME);
map.put(Clients.LAST_MODIFIED, Clients.LAST_MODIFIED);
TABS_PROJECTION_MAP = Collections.unmodifiableMap(map);
map = new HashMap<String, String>();
@ -526,7 +528,7 @@ public class TabsProvider extends ContentProvider {
}
qb.setProjectionMap(TABS_PROJECTION_MAP);
qb.setTables(TABLE_TABS);
qb.setTables(TABLE_TABS + " LEFT OUTER JOIN " + TABLE_CLIENTS + " ON (" + TABLE_TABS + "." + Tabs.CLIENT_GUID + " = " + TABLE_CLIENTS + "." + Clients.GUID + ")");
break;
case CLIENTS_ID:

Просмотреть файл

@ -27,6 +27,8 @@
<!ENTITY awesomebar_default_text "Enter Search or Address">
<!ENTITY remote_tabs "Synced Tabs">
<!ENTITY bookmark "Bookmark">
<!ENTITY bookmark_added "Bookmark added">
<!ENTITY bookmark_removed "Bookmark removed">

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 18 KiB

После

Ширина:  |  Высота:  |  Размер: 18 KiB

Просмотреть файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/background"
android:tileMode="repeat"/>

Просмотреть файл

@ -60,8 +60,7 @@
android:isScrollContainer="false"
android:gravity="center"/>
<view class="org.mozilla.gecko.AboutHomeContent$LinkTextView"
android:id="@+id/all_top_sites_text"
<org.mozilla.gecko.LinkTextView android:id="@+id/all_top_sites_text"
android:layout_width="fill_parent"
android:layout_height="30dip"
android:layout_below="@id/top_sites_grid"
@ -139,8 +138,7 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<view class="org.mozilla.gecko.AboutHomeContent$LinkTextView"
android:id="@+id/last_tabs_open_all"
<org.mozilla.gecko.LinkTextView android:id="@+id/last_tabs_open_all"
android:layout_width="fill_parent"
android:layout_height="47dip"
android:background="@drawable/abouthome_separator"
@ -169,8 +167,7 @@
android:visibility="gone"
android:isScrollContainer="false"/>
<view class="org.mozilla.gecko.AboutHomeContent$LinkTextView"
android:id="@+id/all_addons_text"
<org.mozilla.gecko.LinkTextView android:id="@+id/all_addons_text"
android:layout_width="fill_parent"
android:layout_height="47dip"
android:background="@drawable/abouthome_separator"

Просмотреть файл

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<view class="org.mozilla.gecko.RemoteTabs$TabsListContainer"
android:id="@+id/list_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/tabs_tray_bg_repeat">
<ExpandableListView android:id="@+id/list"
style="@style/TabsList"
android:childDivider="@drawable/tabs_tray_list_divider"
android:dividerHeight="2dip"
android:groupIndicator="@android:color/transparent"/>
</view>
</LinearLayout>

Просмотреть файл

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab"
android:layout_width="fill_parent"
android:layout_height="50dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#E5F2FF"
android:singleLine="true"
android:ellipsize="middle"
android:shadowColor="#000000"
android:shadowRadius="1"
android:shadowDx="0"
android:shadowDy="1"
android:background="@drawable/tabs_tray_list_selector"
android:gravity="center_vertical"/>

Просмотреть файл

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/client"
android:layout_width="fill_parent"
android:layout_height="30dip"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#E5F2FF"
android:singleLine="true"
android:ellipsize="middle"
android:shadowColor="#000000"
android:shadowRadius="1"
android:shadowDx="0"
android:shadowDy="1"
android:background="@drawable/remote_tabs_group_bg_repeat"
android:gravity="center_vertical"/>

Просмотреть файл

@ -20,19 +20,39 @@
android:layout_height="2dp"
android:background="@drawable/tabs_tray_list_divider"/>
<LinearLayout android:id="@+id/add_tab"
android:layout_width="fill_parent"
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="50dip"
android:orientation="horizontal"
android:gravity="center|left"
android:background="@drawable/tabs_tray_list_selector">
android:background="@drawable/tabs_tray_bg_repeat">
<ImageView android:layout_width="20dip"
android:layout_height="20dip"
android:layout_marginLeft="20dip"
android:src="@drawable/tab_new"/>
<ImageButton android:id="@+id/add_tab"
android:layout_width="60dip"
android:layout_height="50dip"
android:layout_alignParentLeft="true"
android:paddingTop="15dip"
android:paddingBottom="15dip"
android:paddingLeft="20dip"
android:paddingRight="20dip"
android:src="@drawable/tab_new"
android:background="@drawable/tabs_tray_list_selector"/>
</LinearLayout>
<org.mozilla.gecko.LinkTextView android:id="@+id/remote_tabs"
android:layout_width="wrap_content"
android:layout_height="50dip"
android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:paddingRight="20dip"
android:text="@string/remote_tabs"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#E5F2FF"
android:shadowColor="#000000"
android:shadowRadius="1"
android:shadowDx="0"
android:shadowDy="1"
android:singleLine="true"
android:ellipsize="middle"
android:visibility="gone"/>
</RelativeLayout>
</view>

Просмотреть файл

@ -34,6 +34,8 @@
<string name="awesomebar_default_text">&awesomebar_default_text;</string>
<string name="remote_tabs">&remote_tabs;</string>
<string name="quit">&quit;</string>
<string name="bookmark">&bookmark;</string>
<string name="bookmark_added">&bookmark_added;</string>

Просмотреть файл

@ -65,6 +65,7 @@ import org.mozilla.gecko.sync.stage.CheckPreconditionsStage;
import org.mozilla.gecko.sync.stage.CompletedStage;
import org.mozilla.gecko.sync.stage.EnsureClusterURLStage;
import org.mozilla.gecko.sync.stage.EnsureKeysStage;
import org.mozilla.gecko.sync.stage.FennecTabsServerSyncStage;
import org.mozilla.gecko.sync.stage.FetchInfoCollectionsStage;
import org.mozilla.gecko.sync.stage.FetchMetaGlobalStage;
import org.mozilla.gecko.sync.stage.GlobalSyncStage;
@ -200,6 +201,7 @@ public class GlobalSession implements CredentialsSource, PrefsSource {
stages.put(Stage.syncClientsEngine, new SyncClientsEngineStage());
// TODO: more stages.
stages.put(Stage.syncTabs, new FennecTabsServerSyncStage());
stages.put(Stage.syncBookmarks, new AndroidBrowserBookmarksServerSyncStage());
stages.put(Stage.syncHistory, new AndroidBrowserHistoryServerSyncStage());
stages.put(Stage.completed, new CompletedStage());

Просмотреть файл

@ -1,39 +1,6 @@
/* ***** 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 Android Sync Client.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Richard Newman <rnewman@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 ***** */
/* 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/. */
package org.mozilla.gecko.sync.net;
@ -46,7 +13,6 @@ import java.security.SecureRandom;
import javax.net.ssl.SSLContext;
import android.util.Log;
import ch.boye.httpclientandroidlib.Header;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.HttpResponse;
@ -75,6 +41,8 @@ import ch.boye.httpclientandroidlib.params.HttpProtocolParams;
import ch.boye.httpclientandroidlib.protocol.BasicHttpContext;
import ch.boye.httpclientandroidlib.protocol.HttpContext;
import org.mozilla.gecko.sync.Logger;
/**
* Provide simple HTTP access to a Sync server or similar.
* Implements Basic Auth by asking its delegate for credentials.
@ -109,11 +77,11 @@ public class BaseResource implements Resource {
public BaseResource(URI uri, boolean rewrite) {
if (rewrite && uri.getHost().equals("localhost")) {
// Rewrite localhost URIs to refer to the special Android emulator loopback passthrough interface.
Log.d(LOG_TAG, "Rewriting " + uri + " to point to " + ANDROID_LOOPBACK_IP + ".");
Logger.debug(LOG_TAG, "Rewriting " + uri + " to point to " + ANDROID_LOOPBACK_IP + ".");
try {
this.uri = new URI(uri.getScheme(), uri.getUserInfo(), ANDROID_LOOPBACK_IP, uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
} catch (URISyntaxException e) {
Log.e(LOG_TAG, "Got error rewriting URI for Android emulator.", e);
Logger.error(LOG_TAG, "Got error rewriting URI for Android emulator.", e);
}
} else {
this.uri = uri;
@ -136,7 +104,7 @@ public class BaseResource implements Resource {
Credentials creds = new UsernamePasswordCredentials(credentials);
Header header = BasicScheme.authenticate(creds, "US-ASCII", false);
request.addHeader(header);
Log.d(LOG_TAG, "Adding auth header " + header);
Logger.trace(LOG_TAG, "Adding Basic Auth header.");
}
/**
@ -204,7 +172,7 @@ public class BaseResource implements Resource {
private void execute() {
try {
HttpResponse response = client.execute(request, context);
Log.i(LOG_TAG, "Response: " + response.getStatusLine().toString());
Logger.debug(LOG_TAG, "Response: " + response.getStatusLine().toString());
delegate.handleHttpResponse(response);
} catch (ClientProtocolException e) {
delegate.handleHttpProtocolException(e);
@ -221,10 +189,10 @@ public class BaseResource implements Resource {
try {
this.prepareClient();
} catch (KeyManagementException e) {
Log.e(LOG_TAG, "Couldn't prepare client.", e);
Logger.error(LOG_TAG, "Couldn't prepare client.", e);
delegate.handleTransportException(e);
} catch (NoSuchAlgorithmException e) {
Log.e(LOG_TAG, "Couldn't prepare client.", e);
Logger.error(LOG_TAG, "Couldn't prepare client.", e);
delegate.handleTransportException(e);
}
this.execute();
@ -232,19 +200,19 @@ public class BaseResource implements Resource {
@Override
public void get() {
Log.i(LOG_TAG, "HTTP GET " + this.uri.toASCIIString());
Logger.debug(LOG_TAG, "HTTP GET " + this.uri.toASCIIString());
this.go(new HttpGet(this.uri));
}
@Override
public void delete() {
Log.i(LOG_TAG, "HTTP DELETE " + this.uri.toASCIIString());
Logger.debug(LOG_TAG, "HTTP DELETE " + this.uri.toASCIIString());
this.go(new HttpDelete(this.uri));
}
@Override
public void post(HttpEntity body) {
Log.i(LOG_TAG, "HTTP POST " + this.uri.toASCIIString());
Logger.debug(LOG_TAG, "HTTP POST " + this.uri.toASCIIString());
HttpPost request = new HttpPost(this.uri);
request.setEntity(body);
this.go(request);
@ -252,7 +220,7 @@ public class BaseResource implements Resource {
@Override
public void put(HttpEntity body) {
Log.i(LOG_TAG, "HTTP PUT " + this.uri.toASCIIString());
Logger.debug(LOG_TAG, "HTTP PUT " + this.uri.toASCIIString());
HttpPut request = new HttpPut(this.uri);
request.setEntity(body);
this.go(request);

Просмотреть файл

@ -0,0 +1,25 @@
/* 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/. */
package org.mozilla.gecko.sync.repositories;
import org.mozilla.gecko.sync.SyncException;
import android.net.Uri;
/**
* Raised when a Content Provider cannot be retrieved.
*
* @author rnewman
*
*/
public class NoContentProviderException extends SyncException {
private static final long serialVersionUID = 1L;
public final Uri requestedProvider;
public NoContentProviderException(Uri requested) {
super();
this.requestedProvider = requested;
}
}

Просмотреть файл

@ -0,0 +1,222 @@
/* 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/. */
package org.mozilla.gecko.sync.repositories.android;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.sync.Logger;
import org.mozilla.gecko.sync.repositories.InactiveSessionException;
import org.mozilla.gecko.sync.repositories.NoContentProviderException;
import org.mozilla.gecko.sync.repositories.NoStoreDelegateException;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.RepositorySession;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionCreationDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFetchRecordsDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionFinishDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionGuidsSinceDelegate;
import org.mozilla.gecko.sync.repositories.delegates.RepositorySessionWipeDelegate;
import org.mozilla.gecko.sync.repositories.domain.Record;
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
import android.content.ContentProviderClient;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.os.RemoteException;
public class FennecTabsRepository extends Repository {
/**
* Note that unlike most repositories  this will only fetch Fennec's tabs,
* and only store tabs from other clients.
*
* It will never retrieve tabs from other clients, or store tabs for Fennec,
* unless you use {@link fetch(String[], RepositorySessionFetchRecordsDelegate)}
* and specify an explicit GUID.
*/
public static class FennecTabsRepositorySession extends RepositorySession {
private static final String LOG_TAG = "FennecTabsSession";
private final ContentProviderClient tabsProvider;
private final ContentProviderClient clientsProvider;
protected ContentProviderClient getContentProvider(final Context context, final Uri uri) throws NoContentProviderException {
ContentProviderClient client = context.getContentResolver().acquireContentProviderClient(uri);
if (client == null) {
throw new NoContentProviderException(uri);
}
return client;
}
protected void releaseProviders() {
try {
clientsProvider.release();
} catch (Exception e) {}
try {
tabsProvider.release();
} catch (Exception e) {}
}
public FennecTabsRepositorySession(Repository repository, Context context) throws NoContentProviderException {
super(repository);
clientsProvider = getContentProvider(context, BrowserContract.Clients.CONTENT_URI);
try {
tabsProvider = getContentProvider(context, BrowserContract.Tabs.CONTENT_URI);
} catch (NoContentProviderException e) {
clientsProvider.release();
throw e;
} catch (Exception e) {
clientsProvider.release();
// Oh, Java.
throw new RuntimeException(e);
}
}
@Override
public void abort() {
releaseProviders();
super.abort();
}
@Override
public void finish(final RepositorySessionFinishDelegate delegate) throws InactiveSessionException {
releaseProviders();
super.finish(delegate);
}
@Override
public void guidsSince(long timestamp,
RepositorySessionGuidsSinceDelegate delegate) {
// Empty until Bug 730039 lands.
delegate.onGuidsSinceSucceeded(new String[] {});
}
@Override
public void fetchSince(long timestamp,
RepositorySessionFetchRecordsDelegate delegate) {
// Empty until Bug 730039 lands.
delegate.onFetchCompleted(now());
}
@Override
public void fetch(String[] guids,
RepositorySessionFetchRecordsDelegate delegate) {
// Incomplete until Bug 730039 lands.
// TODO
delegate.onFetchCompleted(now());
}
@Override
public void fetchAll(RepositorySessionFetchRecordsDelegate delegate) {
// Incomplete until Bug 730039 lands.
// TODO
delegate.onFetchCompleted(now());
}
private static final String TABS_CLIENT_GUID_IS = BrowserContract.Tabs.CLIENT_GUID + " = ?";
private static final String CLIENT_GUID_IS = BrowserContract.Clients.GUID + " = ?";
@Override
public void store(final Record record) throws NoStoreDelegateException {
if (delegate == null) {
Logger.warn(LOG_TAG, "No store delegate.");
throw new NoStoreDelegateException();
}
if (record == null) {
Logger.error(LOG_TAG, "Record sent to store was null");
throw new IllegalArgumentException("Null record passed to FennecTabsRepositorySession.store().");
}
if (!(record instanceof TabsRecord)) {
Logger.error(LOG_TAG, "Can't store anything but a TabsRecord");
throw new IllegalArgumentException("Non-TabsRecord passed to FennecTabsRepositorySession.store().");
}
final TabsRecord tabsRecord = (TabsRecord) record;
Runnable command = new Runnable() {
@Override
public void run() {
Logger.debug(LOG_TAG, "Storing tabs for client " + tabsRecord.guid);
if (!isActive()) {
delegate.onRecordStoreFailed(new InactiveSessionException(null));
return;
}
if (tabsRecord.guid == null) {
delegate.onRecordStoreFailed(new RuntimeException("Can't store record with null GUID."));
return;
}
try {
// This is nice and easy: we *always* store.
final String[] selectionArgs = new String[] { tabsRecord.guid };
if (tabsRecord.deleted) {
try {
Logger.debug(LOG_TAG, "Clearing entry for client " + tabsRecord.guid);
clientsProvider.delete(BrowserContract.Clients.CONTENT_URI,
CLIENT_GUID_IS,
selectionArgs);
delegate.onRecordStoreSucceeded(record);
} catch (Exception e) {
delegate.onRecordStoreFailed(e);
}
return;
}
// If it exists, update the client record; otherwise insert.
final ContentValues clientsCV = tabsRecord.getClientsContentValues();
Logger.debug(LOG_TAG, "Updating clients provider.");
final int updated = clientsProvider.update(BrowserContract.Clients.CONTENT_URI,
clientsCV,
CLIENT_GUID_IS,
selectionArgs);
if (0 == updated) {
clientsProvider.insert(BrowserContract.Clients.CONTENT_URI, clientsCV);
}
// Now insert tabs.
final ContentValues[] tabsArray = tabsRecord.getTabsContentValues();
Logger.debug(LOG_TAG, "Inserting " + tabsArray.length + " tabs for client " + tabsRecord.guid);
tabsProvider.delete(BrowserContract.Tabs.CONTENT_URI, TABS_CLIENT_GUID_IS, selectionArgs);
final int inserted = tabsProvider.bulkInsert(BrowserContract.Tabs.CONTENT_URI, tabsArray);
Logger.trace(LOG_TAG, "Inserted: " + inserted);
delegate.onRecordStoreSucceeded(tabsRecord);
} catch (Exception e) {
Logger.warn(LOG_TAG, "Error storing tabs.", e);
delegate.onRecordStoreFailed(e);
}
}
};
storeWorkQueue.execute(command);
}
@Override
public void wipe(RepositorySessionWipeDelegate delegate) {
try {
tabsProvider.delete(BrowserContract.Tabs.CONTENT_URI, null, null);
clientsProvider.delete(BrowserContract.Clients.CONTENT_URI, null, null);
} catch (RemoteException e) {
Logger.warn(LOG_TAG, "Got RemoteException in wipe.", e);
delegate.onWipeFailed(e);
return;
}
delegate.onWipeSucceeded();
}
}
@Override
public void createSession(RepositorySessionCreationDelegate delegate,
Context context) {
try {
final FennecTabsRepositorySession session = new FennecTabsRepositorySession(this, context);
delegate.onSessionCreated(session);
} catch (Exception e) {
delegate.onSessionCreateFailed(e);
}
}
}

Просмотреть файл

@ -8,11 +8,14 @@ import java.util.ArrayList;
import org.json.simple.JSONObject;
import org.json.simple.JSONArray;
import org.mozilla.gecko.db.BrowserContract;
import org.mozilla.gecko.sync.ExtendedJSONObject;
import org.mozilla.gecko.sync.Logger;
import org.mozilla.gecko.sync.NonArrayJSONException;
import org.mozilla.gecko.sync.Utils;
import android.content.ContentValues;
/**
* Represents a client's collection of tabs.
*
@ -40,7 +43,19 @@ public class TabsRecord extends Record {
String title = obj.getString("title");
String icon = obj.getString("icon");
JSONArray history = obj.getArray("urlHistory");
long lastUsed = obj.getLong("lastUsed");
// Last used is inexplicably a string in seconds. Most of the time.
long lastUsed = 0;
Object lU = obj.get("lastUsed");
if (lU instanceof Number) {
lastUsed = ((Long) lU) * 1000L;
} else if (lU instanceof String) {
try {
lastUsed = Long.parseLong((String) lU, 10) * 1000L;
} catch (NumberFormatException e) {
Logger.debug(LOG_TAG, "Invalid number format in lastUsed: " + lU);
}
}
return new Tab(title, icon, history, lastUsed);
}
@ -50,9 +65,23 @@ public class TabsRecord extends Record {
o.put("title", title);
o.put("icon", icon);
o.put("urlHistory", history);
o.put("lastUsed", lastUsed);
o.put("lastUsed", this.lastUsed / 1000);
return o;
}
public ContentValues toContentValues(String clientGUID, int position) {
ContentValues out = new ContentValues();
out.put(BrowserContract.Tabs.POSITION, position);
out.put(BrowserContract.Tabs.CLIENT_GUID, clientGUID);
out.put(BrowserContract.Tabs.FAVICON, this.icon);
out.put(BrowserContract.Tabs.LAST_USED, this.lastUsed);
out.put(BrowserContract.Tabs.TITLE, this.title);
out.put(BrowserContract.Tabs.URL, (String) this.history.get(0));
out.put(BrowserContract.Tabs.HISTORY, this.history.toJSONString());
return out;
}
}
private static final String LOG_TAG = "TabsRecord";
@ -130,4 +159,21 @@ public class TabsRecord extends Record {
return out;
}
public ContentValues getClientsContentValues() {
ContentValues cv = new ContentValues();
cv.put(BrowserContract.Clients.GUID, this.guid);
cv.put(BrowserContract.Clients.NAME, this.clientName);
cv.put(BrowserContract.Clients.LAST_MODIFIED, this.lastModified);
return cv;
}
public ContentValues[] getTabsContentValues() {
int c = tabs.size();
ContentValues[] out = new ContentValues[c];
for (int i = 0; i < c; i++) {
out[i] = tabs.get(i).toContentValues(this.guid, i);
}
return out;
}
}

Просмотреть файл

@ -0,0 +1,45 @@
/* 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/. */
package org.mozilla.gecko.sync.stage;
import org.mozilla.gecko.sync.repositories.domain.TabsRecord;
import org.mozilla.gecko.sync.CryptoRecord;
import org.mozilla.gecko.sync.repositories.RecordFactory;
import org.mozilla.gecko.sync.repositories.Repository;
import org.mozilla.gecko.sync.repositories.android.FennecTabsRepository;
import org.mozilla.gecko.sync.repositories.domain.Record;
public class FennecTabsServerSyncStage extends ServerSyncStage {
private static final String COLLECTION = "tabs";
public class FennecTabsRecordFactory extends RecordFactory {
@Override
public Record createRecord(Record record) {
TabsRecord r = new TabsRecord();
r.initFromEnvelope((CryptoRecord) record);
return r;
}
}
@Override
protected String getCollection() {
return COLLECTION;
}
@Override
protected String getEngineName() {
return COLLECTION;
}
@Override
protected Repository getLocalRepository() {
return new FennecTabsRepository();
}
@Override
protected RecordFactory getRecordFactory() {
return new FennecTabsRecordFactory();
}
}

Просмотреть файл

@ -57,6 +57,7 @@ public interface GlobalSyncStage {
processClientCommands,
updateEnabledEngines,
*/
syncTabs,
syncBookmarks,
syncHistory,
completed,

Просмотреть файл

@ -42,6 +42,7 @@ import java.net.URISyntaxException;
import org.json.simple.parser.ParseException;
import org.mozilla.gecko.sync.GlobalSession;
import org.mozilla.gecko.sync.Logger;
import org.mozilla.gecko.sync.MetaGlobalException;
import org.mozilla.gecko.sync.NoCollectionKeysSetException;
import org.mozilla.gecko.sync.NonObjectJSONException;
@ -127,17 +128,18 @@ public abstract class ServerSyncStage implements
@Override
public void execute(GlobalSession session) throws NoSuchStageException {
Log.d(LOG_TAG, "Starting execute.");
final String name = getEngineName();
Logger.debug(LOG_TAG, "Starting execute for " + name);
this.session = session;
try {
if (!this.isEnabled()) {
Log.i(LOG_TAG, "Stage disabled; skipping.");
Logger.info(LOG_TAG, "Stage " + name + " disabled; skipping.");
session.advance();
return;
}
} catch (MetaGlobalException e) {
session.abort(e, "Inappropriate meta/global; refusing to execute " + this.getEngineName() + " stage.");
session.abort(e, "Inappropriate meta/global; refusing to execute " + name + " stage.");
return;
}
@ -161,9 +163,9 @@ public abstract class ServerSyncStage implements
session.abort(e, "Invalid persisted JSON for config.");
return;
}
Log.d(LOG_TAG, "Invoking synchronizer.");
Logger.debug(LOG_TAG, "Invoking synchronizer.");
synchronizer.synchronize(session.getContext(), this);
Log.d(LOG_TAG, "Reached end of execute.");
Logger.debug(LOG_TAG, "Reached end of execute.");
}
@Override

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,6 @@
# FreeType 2 top Jamfile.
#
# Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 by
# Copyright 2001-2011 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@ -76,9 +76,10 @@ FT2_COMPONENTS ?= autofit # auto-fitter
cache # cache sub-system
cff # CFF/CEF font driver
cid # PostScript CID-keyed font driver
gzip # support for gzip-compressed files
lzw # support for LZW-compressed files
pcf # PCF font driver
bzip2 # support for bzip2-compressed PCF font
gzip # support for gzip-compressed PCF font
lzw # support for LZW-compressed PCF font
pfr # PFR/TrueDoc font driver
psaux # common PostScript routines module
pshinter # PostScript hinter module
@ -194,7 +195,7 @@ rule RefDoc
actions RefDoc
{
python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.4.3 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h
python $(FT2_SRC)/tools/docmaker/docmaker.py --prefix=ft2 --title=FreeType-2.4.9 --output=$(DOC_DIR) $(FT2_INCLUDE)/freetype/*.h $(FT2_INCLUDE)/freetype/config/*.h
}
RefDoc refdoc ;

Просмотреть файл

@ -1,15 +1,4 @@
Special notes to Unix users
===========================
Please read the file `docs/UPGRADE.UNIX'. It contains important
information regarding the installation of FreeType on Unix systems,
especially GNU based operating systems like GNU/Linux.
FreeType 2's library is called `libfreetype', FreeType 1's library
is called `libttf'. They are *not* compatible!
FreeType 2.4.3
FreeType 2.4.9
==============
Please read the docs/CHANGES file, it contains IMPORTANT
@ -17,6 +6,10 @@
Read the files `docs/INSTALL' for installation instructions.
See the file `docs/LICENSE.TXT' for the available licenses. Note
that we use ranges (`2008-2010') for copyright years also instead of
listing individual years (`2008, 2009, 2010').
The FreeType 2 API reference is located in `docs/reference'; use the
file `ft2-doc.html' as the top entry point. Additional
documentation is available as a separate package from our sites. Go
@ -26,9 +19,9 @@
and download one of the following files.
freetype-doc-2.4.3.tar.bz2
freetype-doc-2.4.3.tar.gz
ftdoc243.zip
freetype-doc-2.4.9.tar.bz2
freetype-doc-2.4.9.tar.gz
ftdoc249.zip
Bugs
@ -51,7 +44,7 @@
----------------------------------------------------------------------
Copyright 2006, 2007, 2008, 2009, 2010 by
Copyright 2006-2011 by
David Turner, Robert Wilhelm, and Werner Lemberg.
This file is part of the FreeType project, and may only be used,

Просмотреть файл

@ -1,6 +1,4 @@
This directory contains freetype2 v2.4.3 downloaded from
This directory contains freetype2 v2.4.9 downloaded from
http://savannah.nongnu.org/download/freetype/
Makefile.in is added for the mozilla build.
Additional patch applied locally:
There are currently no local changes applied the freetype tree.

7
modules/freetype2/autogen.sh Normal file → Executable file
Просмотреть файл

@ -118,9 +118,12 @@ fi
# On MacOS X, the GNU libtool is named `glibtool'.
HOSTOS=`uname`
LIBTOOLIZE=libtoolize
if test "$HOSTOS"x = Darwinx; then
if test "$LIBTOOLIZE"x != x; then
:
elif test "$HOSTOS"x = Darwinx; then
LIBTOOLIZE=glibtoolize
else
LIBTOOLIZE=libtoolize
fi
if test "$ACLOCAL"x = x; then

Просмотреть файл

@ -234,6 +234,11 @@ pcf.ppc.o: $(FTSRC)/pcf/pcf.c
gzip.ppc.o: $(FTSRC)/gzip/ftgzip.c
$(CC) -c $(CFLAGS) -o $@ $<
# FreeType2 library bzip2 support for compressed PCF bitmap fonts
#
bzip2.ppc.o: $(FTSRC)/bzip2/ftbzip2.c
$(CC) -c $(CFLAGS) -o $@ $<
#
# FreeType2 library compress support for compressed PCF bitmap fonts
#
@ -285,8 +290,8 @@ RASTERPPC = raster.ppc.o smooth.ppc.o
FONTDPPC = cff.ppc.o type1.ppc.o type42.ppc.o type1cid.ppc.o truetype.ppc.o\
bdf.ppc.o pcf.ppc.o pfr.ppc.o winfnt.ppc.o
libft2_ppc.a: $(BASEPPC) $(AFITPPC) $(GXVPPC) $(OTVPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) gzip.ppc.o lzw.ppc.o
$(AR) $@ $(BASEPPC) $(AFITPPC) $(GXVPPC) $(OTVPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) gzip.ppc.o lzw.ppc.o
libft2_ppc.a: $(BASEPPC) $(AFITPPC) $(GXVPPC) $(OTVPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) gzip.ppc.o bzip2.ppc.o lzw.ppc.o
$(AR) $@ $(BASEPPC) $(AFITPPC) $(GXVPPC) $(OTVPPC) $(PSPPC) $(RASTERPPC) sfnt.ppc.o ftcache.ppc.o $(FONTDPPC) gzip.ppc.o bzip2.ppc.o lzw.ppc.o
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
#Local Variables:

Просмотреть файл

@ -237,6 +237,12 @@ pcf.ppc.o: FT:src/pcf/pcf.c
gzip.ppc.o: FT:src/gzip/ftgzip.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/gzip/ftgzip.c
#
# FreeType2 library bzip2 support for compressed PCF bitmap fonts
#
bzip2.ppc.o: FT:src/bzip2/ftbzip2.c
$(CC) -c $(CFLAGS) -o $@ /FT/src/bzip2/ftbzip2.c
#
# FreeType2 library compress support for compressed PCF bitmap fonts
#

Просмотреть файл

@ -98,8 +98,8 @@ assign:
# uses separate object modules in lib to make for easier debugging
# also, can make smaller programs if entire engine is not used
ft2_$(CPU).lib: $(OBJBASE) $(OBJAFIT) $(OBJOTV) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) lzw.o gzip.o
oml $@ r $(OBJBASE) $(OBJAFIT) $(OBJOTV) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) lzw.o gzip.o
ft2_$(CPU).lib: $(OBJBASE) $(OBJAFIT) $(OBJOTV) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) lzw.o gzip.o bzip2.o
oml $@ r $(OBJBASE) $(OBJAFIT) $(OBJOTV) $(OBJPS) $(OBJRASTER) $(OBJSFNT) $(OBJCACHE) $(OBJFONTD) lzw.o gzip.o bzip2.o
clean:
-delete \#?.o
@ -262,6 +262,12 @@ pcf.o: $(CORE)pcf/pcf.c
gzip.o: $(CORE)gzip/ftgzip.c
sc $(SCFLAGS) define FAR objname=$@ $<
#
# freetype library bzip2 support for compressed PCF bitmap fonts
#
bzip2.o: $(CORE)bzip2/ftbzip2.c
sc $(SCFLAGS) define FAR objname=$@ $<
#
# freetype library compress support for compressed PCF bitmap fonts
#

Просмотреть файл

@ -4,7 +4,7 @@
/* */
/* Amiga-specific FreeType low-level system interface (body). */
/* */
/* Copyright 1996-2001, 2002, 2005, 2006, 2007 by */
/* Copyright 1996-2001, 2002, 2005, 2006, 2007, 2010 by */
/* David Turner, Robert Wilhelm, Werner Lemberg and Detlef Würkner. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -442,6 +442,14 @@ Free_VecPooled( APTR poolHeader,
stream->read = ft_amiga_stream_io;
stream->close = ft_amiga_stream_close;
if ( !stream->size )
{
ft_amiga_stream_close( stream );
FT_ERROR(( "FT_Stream_Open:" ));
FT_ERROR(( " opened `%s' but zero-sized\n", filepathname ));
return FT_Err_Cannot_Open_Stream;;
}
FT_TRACE1(( "FT_Stream_Open:" ));
FT_TRACE1(( " opened `%s' (%ld bytes) successfully\n",
filepathname, stream->size ));

0
modules/freetype2/builds/atari/gen-purec-patch.sh Normal file → Executable file
Просмотреть файл

Просмотреть файл

@ -17,6 +17,7 @@ Includes = \xB6
Sym-68K = -sym off
COptions = \xB6
-d FT_MACINTOSH=1 \xB6
-d HAVE_FSSPEC=1 \xB6
-d HAVE_FSREF=0 \xB6
-d HAVE_QUICKDRAW_TOOLBOX=1 \xB6
@ -56,6 +57,7 @@ SrcFiles = \xB6
:src:cid:type1cid.c \xB6
# :src:gxvalid:gxvalid.c \xB6
:src:gzip:ftgzip.c \xB6
:src:bzip2:ftbzip2.c \xB6
:src:lzw:ftlzw.c \xB6
:src:otvalid:otvalid.c \xB6
:src:pcf:pcf.c \xB6
@ -100,6 +102,7 @@ ObjFiles-68K = \xB6
"{ObjDir}type1cid.c.o" \xB6
# "{ObjDir}gxvalid.c.o" \xB6
"{ObjDir}ftgzip.c.o" \xB6
"{ObjDir}ftbzip2.c.o" \xB6
"{ObjDir}ftlzw.c.o" \xB6
"{ObjDir}otvalid.c.o" \xB6
"{ObjDir}pcf.c.o" \xB6
@ -177,6 +180,7 @@ FreeType.m68k_cfm.o \xC4\xC4 {ObjFiles-68K} {LibFiles-68K} {\xA5MondoBuild\xA5
"{ObjDir}type1cid.c.o" \xC4 :src:cid:type1cid.c
# "{ObjDir}gxvalid.c.o" \xC4 :src:gxvalid:gxvalid.c
"{ObjDir}ftgzip.c.o" \xC4 :src:gzip:ftgzip.c
"{ObjDir}ftbzip2.c.o" \xC4 :src:bzip2:ftbzip2.c
"{ObjDir}ftlzw.c.o" \xC4 :src:lzw:ftlzw.c
"{ObjDir}otvalid.c.o" \xC4 :src:otvalid:otvalid.c
"{ObjDir}pcf.c.o" \xC4 :src:pcf:pcf.c

Просмотреть файл

@ -16,6 +16,7 @@ Includes = \xB6
Sym-68K = -sym off
COptions = \xB6
-d FT_MACINTOSH=1 \xB6
-d HAVE_FSSPEC=1 \xB6
-d HAVE_FSREF=0 \xB6
-d HAVE_QUICKDRAW_TOOLBOX=1 \xB6
@ -55,6 +56,7 @@ SrcFiles = \xB6
:src:cid:type1cid.c \xB6
:src:gxvalid:gxvalid.c \xB6
:src:gzip:ftgzip.c \xB6
:src:bzip2:ftbzip2.c \xB6
:src:lzw:ftlzw.c \xB6
:src:otvalid:otvalid.c \xB6
:src:pcf:pcf.c \xB6
@ -99,6 +101,7 @@ ObjFiles-68K = \xB6
"{ObjDir}type1cid.c.o" \xB6
"{ObjDir}gxvalid.c.o" \xB6
"{ObjDir}ftgzip.c.o" \xB6
"{ObjDir}ftbzip2.c.o" \xB6
"{ObjDir}ftlzw.c.o" \xB6
"{ObjDir}otvalid.c.o" \xB6
"{ObjDir}pcf.c.o" \xB6
@ -176,6 +179,7 @@ FreeType.m68k_far.o \xC4\xC4 {ObjFiles-68K} {LibFiles-68K} {\xA5MondoBuild\xA5
"{ObjDir}type1cid.c.o" \xC4 :src:cid:type1cid.c
"{ObjDir}gxvalid.c.o" \xC4 :src:gxvalid:gxvalid.c
"{ObjDir}ftgzip.c.o" \xC4 :src:gzip:ftgzip.c
"{ObjDir}ftbzip2.c.o" \xC4 :src:bzip2:ftbzip2.c
"{ObjDir}ftlzw.c.o" \xC4 :src:lzw:ftlzw.c
"{ObjDir}otvalid.c.o" \xC4 :src:otvalid:otvalid.c
"{ObjDir}pcf.c.o" \xC4 :src:pcf:pcf.c

Просмотреть файл

@ -17,6 +17,7 @@ Includes = \xB6
Sym-PPC = -sym off
PPCCOptions = \xB6
-d FT_MACINTOSH=1 \xB6
-d HAVE_FSSPEC=1 \xB6
-d HAVE_FSREF=1 \xB6
-d HAVE_QUICKDRAW_TOOLBOX=1 \xB6
@ -56,6 +57,7 @@ SrcFiles = \xB6
:src:cid:type1cid.c \xB6
:src:gxvalid:gxvalid.c \xB6
:src:gzip:ftgzip.c \xB6
:src:bzip2:ftbzip2.c \xB6
:src:lzw:ftlzw.c \xB6
:src:otvalid:otvalid.c \xB6
:src:pcf:pcf.c \xB6
@ -100,6 +102,7 @@ ObjFiles-PPC = \xB6
"{ObjDir}type1cid.c.x" \xB6
"{ObjDir}gxvalid.c.x" \xB6
"{ObjDir}ftgzip.c.x" \xB6
"{ObjDir}ftbzip2.c.x" \xB6
"{ObjDir}ftlzw.c.x" \xB6
"{ObjDir}otvalid.c.x" \xB6
"{ObjDir}pcf.c.x" \xB6
@ -180,6 +183,7 @@ FreeType.ppc_carbon.o \xC4\xC4 {ObjFiles-PPC} {LibFiles-PPC} {\xA5MondoBuild\x
"{ObjDir}type1cid.c.x" \xC4 :src:cid:type1cid.c
"{ObjDir}gxvalid.c.x" \xC4 :src:gxvalid:gxvalid.c
"{ObjDir}ftgzip.c.x" \xC4 :src:gzip:ftgzip.c
"{ObjDir}ftbzip2.c.x" \xC4 :src:bzip2:ftbzip2.c
"{ObjDir}ftlzw.c.x" \xC4 :src:lzw:ftlzw.c
"{ObjDir}otvalid.c.x" \xC4 :src:otvalid:otvalid.c
"{ObjDir}pcf.c.x" \xC4 :src:pcf:pcf.c

Просмотреть файл

@ -17,6 +17,7 @@ Includes = \xB6
Sym-PPC = -sym off
PPCCOptions = \xB6
-d FT_MACINTOSH=1 \xB6
-d HAVE_FSSPEC=1 \xB6
-d HAVE_FSREF=0 \xB6
-d HAVE_QUICKDRAW_TOOLBOX=1 \xB6
@ -56,6 +57,7 @@ SrcFiles = \xB6
:src:cid:type1cid.c \xB6
:src:gxvalid:gxvalid.c \xB6
:src:gzip:ftgzip.c \xB6
:src:bzip2:ftbzip2.c \xB6
:src:lzw:ftlzw.c \xB6
:src:otvalid:otvalid.c \xB6
:src:pcf:pcf.c \xB6
@ -100,6 +102,7 @@ ObjFiles-PPC = \xB6
"{ObjDir}type1cid.c.x" \xB6
"{ObjDir}gxvalid.c.x" \xB6
"{ObjDir}ftgzip.c.x" \xB6
"{ObjDir}ftbzip2.c.x" \xB6
"{ObjDir}ftlzw.c.x" \xB6
"{ObjDir}otvalid.c.x" \xB6
"{ObjDir}pcf.c.x" \xB6
@ -180,6 +183,7 @@ FreeType.ppc_classic.o \xC4\xC4 {ObjFiles-PPC} {LibFiles-PPC} {\xA5MondoBuild\
"{ObjDir}type1cid.c.x" \xC4 :src:cid:type1cid.c
"{ObjDir}gxvalid.c.x" \xC4 :src:gxvalid:gxvalid.c
"{ObjDir}ftgzip.c.x" \xC4 :src:gzip:ftgzip.c
"{ObjDir}ftbzip2.c.x" \xC4 :src:bzip2:ftbzip2.c
"{ObjDir}ftlzw.c.x" \xC4 :src:lzw:ftlzw.c
"{ObjDir}otvalid.c.x" \xC4 :src:otvalid:otvalid.c
"{ObjDir}pcf.c.x" \xC4 :src:pcf:pcf.c

0
modules/freetype2/builds/mac/ascii2mpw.py Normal file → Executable file
Просмотреть файл

Просмотреть файл

@ -171,6 +171,7 @@ typedef short ResourceIndex;
#define PREFER_LWFN 1
#endif
#ifdef FT_MACINTOSH
#if !HAVE_QUICKDRAW_CARBON /* QuickDraw is deprecated since Mac OS X 10.4 */
@ -1527,5 +1528,7 @@ typedef short ResourceIndex;
}
#endif /* FT_MACINTOSH */
/* END */

Просмотреть файл

@ -36,6 +36,7 @@ PRJ_EXPORTS
../../include/freetype/ftglyph.h freetype/ftglyph.h
../../include/freetype/ftgxval.h freetype/ftgxval.h
../../include/freetype/ftgzip.h freetype/ftgzip.h
../../include/freetype/ftbzip2.h freetype/ftbzip2.h
../../include/freetype/ftimage.h freetype/ftimage.h
../../include/freetype/ftincrem.h freetype/ftincrem.h
../../include/freetype/ftlcdfil.h freetype/ftlcdfil.h

Просмотреть файл

@ -64,6 +64,10 @@ sourcepath ..\..\src\gzip
source ftgzip.c
sourcepath ..\..\src\bzip2
source ftbzip2.c
sourcepath ..\..\src\lzw
source ftlzw.c
@ -126,6 +130,7 @@ userinclude ..\..\src\cff
userinclude ..\..\src\cid
userinclude ..\..\src\gxvalid
userinclude ..\..\src\gzip
userinclude ..\..\src\bzip2
userinclude ..\..\src\lzw
userinclude ..\..\src\otvalid
userinclude ..\..\src\pcf

Просмотреть файл

@ -122,6 +122,7 @@ ifdef check_platform
#
is_unix := $(strip $(wildcard /sbin/init) \
$(wildcard /usr/sbin/init) \
$(wildcard /dev/null) \
$(wildcard /hurd/auth))
ifneq ($(is_unix),)
@ -199,7 +200,7 @@ dist:
currdir=`pwd` ; \
for f in `find . -wholename '*/.git' -prune \
-o -name .cvsignore \
-o -name .gitignore \
-o -type d \
-o -print` ; do \
ln -s $$currdir/$$f tmp/$$f ; \

2124
modules/freetype2/builds/unix/aclocal.m4 поставляемый

Разница между файлами не показана из-за своего большого размера Загрузить разницу

66
modules/freetype2/builds/unix/config.guess поставляемый Normal file → Executable file
Просмотреть файл

@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012 Free Software Foundation, Inc.
timestamp='2010-09-24'
timestamp='2012-02-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -17,9 +17,7 @@ timestamp='2010-09-24'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@ -57,8 +55,8 @@ GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
Software Foundation, Inc.
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -92,7 +90,7 @@ if test $# != 0; then
exit 1
fi
trap 'exit 1' HUP INT TERM
trap 'exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
@ -106,7 +104,7 @@ trap 'exit 1' HUP INT TERM
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" HUP INT PIPE TERM ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
@ -145,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@ -270,7 +268,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@ -789,13 +790,12 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
@ -804,6 +804,9 @@ EOF
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
@ -858,6 +861,13 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@ -879,20 +889,29 @@ EOF
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-gnu
exit ;;
crisv32:Linux:*:*)
echo crisv32-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-gnu
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
LIBC=gnu
@ -934,7 +953,7 @@ EOF
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
@ -969,13 +988,13 @@ EOF
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-tilera-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@ -1306,6 +1325,9 @@ EOF
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше