Merge last green PGO from inbound to central
|
@ -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)
|
||||
|
|
Двоичные данные
browser/themes/gnomestripe/places/livemark-item.png
До Ширина: | Высота: | Размер: 3.8 KiB После Ширина: | Высота: | Размер: 863 B |
Двоичные данные
browser/themes/pinstripe/places/livemark-item.png
До Ширина: | Высота: | Размер: 3.8 KiB После Ширина: | Высота: | Размер: 863 B |
Двоичные данные
browser/themes/winstripe/places/livemark-item.png
До Ширина: | Высота: | Размер: 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();
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
function doCheck(){
|
||||
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();
|
||||
}
|
||||
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() {
|
||||
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();
|
||||
}
|
||||
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();
|
||||
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,12 +199,15 @@ 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);
|
||||
|
||||
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 ®s)
|
||||
{
|
||||
|
||||
/* 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 ®s)
|
||||
: 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() == ®s);
|
||||
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 ®s);
|
||||
|
||||
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 ®s;
|
||||
JSScript *script;
|
||||
uint32_t pcOffset;
|
||||
JSTryNote *tn, *tnEnd;
|
||||
void settle();
|
||||
public:
|
||||
TryNoteIter(const FrameRegs ®s);
|
||||
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;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
|
|
137
mfbt/STYLE
|
@ -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,14 +91,21 @@ 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();
|
||||
finishActivity();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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) {
|
||||
|
@ -103,7 +117,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
|
||||
sListItemHeight = (int) (TABS_LIST_ITEM_HEIGHT * metrics.density);
|
||||
sAddTabHeight = (int) (TABS_ADD_TAB_HEIGHT * metrics.density);
|
||||
sAddTabHeight = (int) (TABS_ADD_TAB_HEIGHT * metrics.density);
|
||||
sPreferredHeight = (int) (0.67 * metrics.heightPixels);
|
||||
sMaxHeight = (int) (sPreferredHeight + (0.33 * sListItemHeight));
|
||||
|
||||
|
@ -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
|
||||
|
@ -118,7 +137,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
super.onDestroy();
|
||||
Tabs.getInstance().unregisterOnTabsChangedListener(this);
|
||||
}
|
||||
|
||||
|
||||
public void onTabChanged(Tab tab, Tabs.TabEvents msg) {
|
||||
if (Tabs.getInstance().getCount() == 1)
|
||||
finishActivity();
|
||||
|
@ -135,7 +154,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
mList.setSelection(selected);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int position = mTabsAdapter.getPositionForTab(tab);
|
||||
if (position == -1)
|
||||
return;
|
||||
|
@ -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,7 +211,36 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Adapter to bind tabs into a list
|
||||
// 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) {
|
||||
mContext = context;
|
||||
|
@ -199,7 +253,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
for (int i = 0; i < tabs.size(); i++) {
|
||||
mTabs.add(tabs.get(i));
|
||||
}
|
||||
|
||||
|
||||
mOnInfoClickListener = new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
Tabs.getInstance().selectTab(Integer.parseInt((String) v.getTag()));
|
||||
|
@ -225,7 +279,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
public int getCount() {
|
||||
return mTabs.size();
|
||||
}
|
||||
|
||||
|
||||
public Tab getItem(int position) {
|
||||
return mTabs.get(position);
|
||||
}
|
||||
|
@ -274,7 +328,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
info.setOnClickListener(mOnInfoClickListener);
|
||||
|
||||
assignValues(convertView, tab);
|
||||
|
||||
|
||||
ImageButton close = (ImageButton) convertView.findViewById(R.id.close);
|
||||
if (mTabs.size() > 1) {
|
||||
close.setTag(String.valueOf(tab.getId()));
|
||||
|
@ -293,7 +347,7 @@ public class TabsTray extends Activity implements Tabs.OnTabsChangedListener {
|
|||
@Override
|
||||
public void notifyDataSetInvalidated() {
|
||||
}
|
||||
|
||||
|
||||
private Context mContext;
|
||||
private ArrayList<Tab> mTabs;
|
||||
private LayoutInflater mInflater;
|
||||
|
|
|
@ -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,16 +60,15 @@
|
|||
android:isScrollContainer="false"
|
||||
android:gravity="center"/>
|
||||
|
||||
<view class="org.mozilla.gecko.AboutHomeContent$LinkTextView"
|
||||
android:id="@+id/all_top_sites_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="30dip"
|
||||
android:layout_below="@id/top_sites_grid"
|
||||
android:layout_marginTop="7dip"
|
||||
android:textColor="#22629e"
|
||||
android:textSize="12sp"
|
||||
android:gravity="top|center_horizontal"
|
||||
android:text="@string/abouthome_top_sites_browse"/>
|
||||
<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"
|
||||
android:layout_marginTop="7dip"
|
||||
android:textColor="#22629e"
|
||||
android:textSize="12sp"
|
||||
android:gravity="top|center_horizontal"
|
||||
android:text="@string/abouthome_top_sites_browse"/>
|
||||
|
||||
<RelativeLayout android:id="@+id/sync_box_container"
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -139,16 +138,15 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<view class="org.mozilla.gecko.AboutHomeContent$LinkTextView"
|
||||
android:id="@+id/last_tabs_open_all"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="47dip"
|
||||
android:background="@drawable/abouthome_separator"
|
||||
android:textColor="#22629e"
|
||||
android:textSize="12sp"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:text="@string/abouthome_last_tabs_open"/>
|
||||
<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"
|
||||
android:textColor="#22629e"
|
||||
android:textSize="12sp"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:text="@string/abouthome_last_tabs_open"/>
|
||||
|
||||
<TextView android:id="@+id/recommended_addons_title"
|
||||
android:layout_width="fill_parent"
|
||||
|
@ -169,16 +167,15 @@
|
|||
android:visibility="gone"
|
||||
android:isScrollContainer="false"/>
|
||||
|
||||
<view class="org.mozilla.gecko.AboutHomeContent$LinkTextView"
|
||||
android:id="@+id/all_addons_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="47dip"
|
||||
android:background="@drawable/abouthome_separator"
|
||||
android:textColor="#22629e"
|
||||
android:textSize="12sp"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:text="@string/abouthome_addons_browse"/>
|
||||
<org.mozilla.gecko.LinkTextView android:id="@+id/all_addons_text"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="47dip"
|
||||
android:background="@drawable/abouthome_separator"
|
||||
android:textColor="#22629e"
|
||||
android:textSize="12sp"
|
||||
android:gravity="center"
|
||||
android:visibility="gone"
|
||||
android:text="@string/abouthome_addons_browse"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -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"
|
||||
android:layout_height="50dip"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center|left"
|
||||
android:background="@drawable/tabs_tray_list_selector">
|
||||
<RelativeLayout android:layout_width="fill_parent"
|
||||
android:layout_height="50dip"
|
||||
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>
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
<string name="choose_file">&choose_file;</string>
|
||||
|
||||
<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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 ));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ; \
|
||||
|
|
|
@ -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
|
||||
|
@ -181,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
fi
|
||||
;;
|
||||
*)
|
||||
os=netbsd
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
|
@ -224,7 +222,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
;;
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
;;
|
||||
esac
|
||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||
|
@ -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
|
||||
|
@ -296,7 +297,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
echo s390-ibm-zvmoe
|
||||
exit ;;
|
||||
*:OS400:*:*)
|
||||
echo powerpc-ibm-os400
|
||||
echo powerpc-ibm-os400
|
||||
exit ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
|
@ -395,23 +396,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
|||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||
# be no problem.
|
||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
exit ;;
|
||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
m68k:machten:*:*)
|
||||
echo m68k-apple-machten${UNAME_RELEASE}
|
||||
exit ;;
|
||||
|
@ -481,8 +482,8 @@ EOF
|
|||
echo m88k-motorola-sysv3
|
||||
exit ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||
then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||
|
@ -495,7 +496,7 @@ EOF
|
|||
else
|
||||
echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit ;;
|
||||
|
@ -595,52 +596,52 @@ EOF
|
|||
9000/[678][0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
|
@ -731,22 +732,22 @@ EOF
|
|||
exit ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit ;;
|
||||
|
@ -770,14 +771,14 @@ EOF
|
|||
exit ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
5000:UNIX_System_V:4.*:*)
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
|
@ -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,15 +804,18 @@ 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
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
exit ;;
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
*:Interix*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
|
@ -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 ;;
|
||||
|
@ -867,7 +877,7 @@ EOF
|
|||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
|
@ -879,20 +889,29 @@ EOF
|
|||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
|
||||
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
|
||||
|
@ -960,7 +979,7 @@ EOF
|
|||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
exit ;;
|
||||
sh64*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sh*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
|
@ -969,16 +988,16 @@ 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
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||
|
@ -987,11 +1006,11 @@ EOF
|
|||
echo i386-sequent-sysv4
|
||||
exit ;;
|
||||
i*86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit ;;
|
||||
i*86:OS/2:*:*)
|
||||
|
@ -1023,7 +1042,7 @@ EOF
|
|||
fi
|
||||
exit ;;
|
||||
i*86:*:5:[678]*)
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
case `/bin/uname -X | grep "^Machine"` in
|
||||
*486*) UNAME_MACHINE=i486 ;;
|
||||
*Pentium) UNAME_MACHINE=i586 ;;
|
||||
|
@ -1051,13 +1070,13 @@ EOF
|
|||
exit ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit ;;
|
||||
|
@ -1092,8 +1111,8 @@ EOF
|
|||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
||||
OS_REL='.3'
|
||||
test -r /etc/.relid \
|
||||
|
@ -1136,10 +1155,10 @@ EOF
|
|||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
|
@ -1165,11 +1184,11 @@ EOF
|
|||
exit ;;
|
||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||
echo powerpc-be-beos
|
||||
exit ;;
|
||||
|
@ -1282,13 +1301,13 @@ EOF
|
|||
echo pdp10-unknown-its
|
||||
exit ;;
|
||||
SEI:*:*:SEIUX)
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:DragonFly:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit ;;
|
||||
*:*VMS:*:*)
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
case "${UNAME_MACHINE}" in
|
||||
A*) echo alpha-dec-vms ; exit ;;
|
||||
I*) echo ia64-dec-vms ; exit ;;
|
||||
|
@ -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
|
||||
|
@ -1328,11 +1350,11 @@ main ()
|
|||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|