Merge last green changeset from inbound to mozilla-central

This commit is contained in:
Matt Brubeck 2012-02-29 10:47:38 -08:00
commit c52c92d647
365 changed files with 8223 additions and 6524 deletions

View File

@ -43,6 +43,8 @@
#include "nsHyperTextAccessible.h"
#include "nsRoleMap.h"
#include "nsIPersistentProperties2.h"
AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
void

View File

@ -112,7 +112,7 @@ StyleInfo::Margin(css::Side aSide, nsAString& aValue)
}
void
StyleInfo::Format(const nscolor& aValue, nsString& aFormattedValue)
StyleInfo::FormatColor(const nscolor& aValue, nsString& aFormattedValue)
{
// Combine the string like rgb(R, G, B) from nscolor.
aFormattedValue.AppendLiteral("rgb(");
@ -123,3 +123,11 @@ StyleInfo::Format(const nscolor& aValue, nsString& aFormattedValue)
aFormattedValue.AppendInt(NS_GET_B(aValue));
aFormattedValue.Append(')');
}
void
StyleInfo::FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue)
{
nsCSSKeyword keyword =
nsCSSProps::ValueToKeywordEnum(aValue, nsCSSProps::kFontStyleKTable);
AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(keyword), aFormattedValue);
}

View File

@ -60,7 +60,8 @@ public:
void MarginTop(nsAString& aValue) { Margin(css::eSideTop, aValue); }
void MarginBottom(nsAString& aValue) { Margin(css::eSideBottom, aValue); }
static void Format(const nscolor& aValue, nsString& aFormattedValue);
static void FormatColor(const nscolor& aValue, nsString& aFormattedValue);
static void FormatFontStyle(const nscoord& aValue, nsAString& aFormattedValue);
private:
StyleInfo() MOZ_DELETE;

View File

@ -74,8 +74,6 @@ const char* const kCopyValue = nsnull;
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] =
{
// CSS name CSS value Attribute name Attribute value
{ "font-family", kAnyValue, &nsGkAtoms::font_family, kCopyValue },
{ "font-style", kAnyValue, &nsGkAtoms::font_style, kCopyValue },
{ "text-decoration", "line-through", &nsGkAtoms::textLineThroughStyle, "solid" },
{ "text-decoration", "underline", &nsGkAtoms::textUnderlineStyle, "solid" },
{ "vertical-align", kAnyValue, &nsGkAtoms::textPosition, kCopyValue }
@ -155,43 +153,43 @@ nsTextAttrsMgr::GetAttributes(nsIPersistentProperties *aAttributes,
// "language" text attribute
nsLangTextAttr langTextAttr(mHyperTextAcc, hyperTextElm, offsetNode);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&langTextAttr));
// "font-family" text attribute
nsCSSTextAttr fontFamilyTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontFamilyTextAttr));
// "font-style" text attribute
nsCSSTextAttr fontStyleTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontStyleTextAttr));
textAttrArray.AppendElement(&langTextAttr);
// "text-line-through-style" text attribute
nsCSSTextAttr lineThroughTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&lineThroughTextAttr));
nsCSSTextAttr lineThroughTextAttr(0, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&lineThroughTextAttr);
// "text-underline-style" text attribute
nsCSSTextAttr underlineTextAttr(3, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&underlineTextAttr));
nsCSSTextAttr underlineTextAttr(1, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&underlineTextAttr);
// "text-position" text attribute
nsCSSTextAttr posTextAttr(4, hyperTextElm, offsetElm);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&posTextAttr));
nsCSSTextAttr posTextAttr(2, hyperTextElm, offsetElm);
textAttrArray.AppendElement(&posTextAttr);
// "background-color" text attribute
nsBGColorTextAttr bgColorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&bgColorTextAttr));
textAttrArray.AppendElement(&bgColorTextAttr);
// "color" text attribute
ColorTextAttr colorTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&colorTextAttr));
textAttrArray.AppendElement(&colorTextAttr);
// "font-family" text attribute
FontFamilyTextAttr fontFamilyTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontFamilyTextAttr);
// "font-size" text attribute
nsFontSizeTextAttr fontSizeTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontSizeTextAttr));
textAttrArray.AppendElement(&fontSizeTextAttr);
// "font-style" text attribute
FontStyleTextAttr fontStyleTextAttr(rootFrame, frame);
textAttrArray.AppendElement(&fontStyleTextAttr);
// "font-weight" text attribute
nsFontWeightTextAttr fontWeightTextAttr(rootFrame, frame);
textAttrArray.AppendElement(static_cast<nsITextAttr*>(&fontWeightTextAttr));
textAttrArray.AppendElement(&fontWeightTextAttr);
// Expose text attributes if applicable.
if (aAttributes) {
@ -391,7 +389,7 @@ void
nsBGColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
{
nsAutoString value;
StyleInfo::Format(aValue, value);
StyleInfo::FormatColor(aValue, value);
aFormattedValue = value;
}
@ -453,11 +451,55 @@ void
ColorTextAttr::Format(const nscolor& aValue, nsAString& aFormattedValue)
{
nsAutoString value;
StyleInfo::Format(aValue, value);
StyleInfo::FormatColor(aValue, value);
aFormattedValue = value;
}
////////////////////////////////////////////////////////////////////////////////
// FontFamilyTextAttr
////////////////////////////////////////////////////////////////////////////////
FontFamilyTextAttr::FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nsAutoString>(aFrame == nsnull)
{
mIsRootDefined = GetFontFamily(aRootFrame, mRootNativeValue);
if (aFrame)
mIsDefined = GetFontFamily(aFrame, mNativeValue);
}
bool
FontFamilyTextAttr::GetValueFor(nsIContent* aElm, nsAutoString* aValue)
{
nsIFrame* frame = aElm->GetPrimaryFrame();
if (!frame)
return false;
return GetFontFamily(frame, *aValue);
}
void
FontFamilyTextAttr::Format(const nsAutoString& aValue,
nsAString& aFormattedValue)
{
aFormattedValue = aValue;
}
bool
FontFamilyTextAttr::GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily)
{
nsRefPtr<nsFontMetrics> fm;
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
gfxFont* font = fontGroup->GetFontAt(0);
gfxFontEntry* fontEntry = font->GetFontEntry();
aFamily = fontEntry->FamilyName();
return true;
}
////////////////////////////////////////////////////////////////////////////////
// nsFontSizeTextAttr
////////////////////////////////////////////////////////////////////////////////
@ -482,7 +524,7 @@ nsFontSizeTextAttr::GetValueFor(nsIContent *aContent, nscoord *aValue)
nsIFrame *frame = aContent->GetPrimaryFrame();
if (!frame)
return false;
*aValue = GetFontSize(frame);
return true;
}
@ -494,7 +536,7 @@ nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
//
// Note: according to IA2, "The conversion doesn't have to be exact.
// The intent is to give the user a feel for the size of the text."
//
//
// ATK does not specify a unit and will likely follow IA2 here.
//
// XXX todo: consider sharing this code with layout module? (bug 474621)
@ -516,6 +558,41 @@ nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
}
////////////////////////////////////////////////////////////////////////////////
// FontStyleTextAttr
////////////////////////////////////////////////////////////////////////////////
FontStyleTextAttr::FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame) :
nsTextAttr<nscoord>(!aFrame)
{
mRootNativeValue = aRootFrame->GetStyleFont()->mFont.style;
mIsRootDefined = true;
if (aFrame) {
mNativeValue = aFrame->GetStyleFont()->mFont.style;
mIsDefined = true;
}
}
bool
FontStyleTextAttr::GetValueFor(nsIContent* aContent, nscoord* aValue)
{
nsIFrame* frame = aContent->GetPrimaryFrame();
if (frame) {
*aValue = frame->GetStyleFont()->mFont.style;
return true;
}
return false;
}
void
FontStyleTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
{
StyleInfo::FormatFontStyle(aValue, aFormattedValue);
}
////////////////////////////////////////////////////////////////////////////////
// nsFontWeightTextAttr
////////////////////////////////////////////////////////////////////////////////

View File

@ -41,17 +41,10 @@
class nsHyperTextAccessible;
#include "nsIDOMNode.h"
#include "nsIDOMElement.h"
#include "nsIContent.h"
#include "nsIFrame.h"
#include "nsIPersistentProperties2.h"
#include "nsCOMPtr.h"
#include "nsString.h"
class nsITextAttr;
/**
@ -100,7 +93,6 @@ public:
PRInt32 *aEndHTOffset = nsnull);
protected:
/**
* Calculates range (start and end offsets) of text where the text attributes
* are stretched. New offsets may be smaller if one of text attributes changes
@ -326,6 +318,30 @@ protected:
};
/**
* Class is used for the work with "font-family" text attribute in
* nsTextAttrsMgr class.
*/
class FontFamilyTextAttr : public nsTextAttr<nsAutoString>
{
public:
FontFamilyTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::font_family; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nsAutoString* aValue);
virtual void Format(const nsAutoString& aValue, nsAString& aFormattedValue);
private:
bool GetFontFamily(nsIFrame* aFrame, nsAutoString& aFamily);
};
/**
* Class is used for the work with "font-size" text attribute in nsTextAttrsMgr
* class.
@ -358,6 +374,26 @@ private:
};
/**
* Class is used for the work with "font-style" text attribute in nsTextAttrsMgr
* class.
*/
class FontStyleTextAttr : public nsTextAttr<nscoord>
{
public:
FontStyleTextAttr(nsIFrame* aRootFrame, nsIFrame* aFrame);
// nsITextAttr
virtual nsIAtom* GetName() const { return nsGkAtoms::font_style; }
protected:
// nsTextAttr
virtual bool GetValueFor(nsIContent* aContent, nscoord* aValue);
virtual void Format(const nscoord &aValue, nsAString &aFormattedValue);
};
/**
* Class is used for the work with "font-weight" text attribute in
* nsTextAttrsMgr class.

View File

@ -46,7 +46,6 @@
#include "AccCollector.h"
#include "nsAccessibleWrap.h"
#include "nsTextAttrs.h"
#include "nsFrameSelection.h"
#include "nsISelectionController.h"

View File

@ -45,6 +45,8 @@
#include "nsHyperTextAccessible.h"
#include "nsIPersistentProperties2.h"
// IUnknown
STDMETHODIMP

View File

@ -208,6 +208,39 @@ const kBoldFontWeight =
const kInputFontSize = WIN ?
"10pt" : (MAC ? "8pt" : function() { return true; });
const kAbsentFontFamily =
function(aFontFamily) { return aFontFamily != "sans-serif"; }
const kInputFontFamily =
function(aFontFamily) { return aFontFamily != "sans-serif"; }
const kMonospaceFontFamily =
function(aFontFamily) { return aFontFamily != "monospace"; }
const kSansSerifFontFamily =
function(aFontFamily) { return aFontFamily != "sans-serif"; }
const kSerifFontFamily =
function(aFontFamily) { return aFontFamily != "serif"; }
const kCursiveFontFamily = WIN ? "Comic Sans MS" :
(LINUX ? "DejaVu Serif" : "MacFont");
/**
* Return used font from the given computed style.
*/
function fontFamily(aComputedStyle)
{
var name = aComputedStyle.fontFamily;
switch (name) {
case "monospace":
return kMonospaceFontFamily;
case "sans-serif":
return kSansSerifFontFamily;
case "serif":
return kSerifFontFamily;
default:
return name;
}
}
/**
* Build an object of default text attributes expected for the given accessible.
*
@ -216,7 +249,7 @@ const kInputFontSize = WIN ?
* @param aFontWeight [in, optional] kBoldFontWeight or kNormalFontWeight,
* default value is kNormalFontWeight
*/
function buildDefaultTextAttrs(aID, aFontSize, aFontWeight)
function buildDefaultTextAttrs(aID, aFontSize, aFontWeight, aFontFamily)
{
var elm = getNode(aID);
var computedStyle = document.defaultView.getComputedStyle(elm, "");
@ -229,7 +262,7 @@ function buildDefaultTextAttrs(aID, aFontSize, aFontWeight)
"background-color": bgColor,
"font-weight": aFontWeight ? aFontWeight : kNormalFontWeight,
"color": computedStyle.color,
"font-family": computedStyle.fontFamily,
"font-family": aFontFamily ? aFontFamily : fontFamily(computedStyle),
"text-position": computedStyle.verticalAlign
};

View File

@ -263,7 +263,7 @@
// Walk from span with font-style to the one with font-family.
tempElem = tempElem.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = { "font-family": gComputedStyle.fontFamily };
attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 70, attrs, defAttrs, 69, 83);
attrs = {};
@ -281,6 +281,7 @@
attrs = {};
testTextAttrs(ID, 123, attrs, defAttrs, 122, 130);
//////////////////////////////////////////////////////////////////////////
// area10, different single style spans in non-styled paragraph
ID = "area10";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
@ -316,7 +317,7 @@
// Walk from span with font-style to the one with font-family.
tempElem = tempElem.nextSibling.nextSibling;
gComputedStyle = document.defaultView.getComputedStyle(tempElem, "");
attrs = {"font-family": gComputedStyle.fontFamily};
attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 71, attrs, defAttrs, 70, 84);
attrs = {};
@ -334,6 +335,7 @@
attrs = {};
testTextAttrs(ID, 124, attrs, defAttrs, 123, 131);
//////////////////////////////////////////////////////////////////////////
// area11, "font-weight" tests
ID = "area11";
defAttrs = buildDefaultTextAttrs(ID, "12pt", kBoldFontWeight);
@ -373,7 +375,8 @@
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
ID = "area14";
defAttrs = buildDefaultTextAttrs(ID, kInputFontSize);
defAttrs = buildDefaultTextAttrs(ID, kInputFontSize,
kNormalFontWeight, kInputFontFamily);
attrs = { };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 0);
@ -404,6 +407,36 @@
// p
testTextAttrs(ID, 23, { }, { }, 23, 24);
//////////////////////////////////////////////////////////////////////////
// area16, "font-family" tests
ID = "area16";
defAttrs = buildDefaultTextAttrs(ID, "12pt");
testDefaultTextAttrs(ID, defAttrs);
attrs = { "font-family": kMonospaceFontFamily };
testTextAttrs(ID, 0, attrs, defAttrs, 0, 4);
attrs = { };
testTextAttrs(ID, 4, attrs, defAttrs, 4, 9);
attrs = { "font-family": kSerifFontFamily };
testTextAttrs(ID, 9, attrs, defAttrs, 9, 13);
attrs = { };
testTextAttrs(ID, 13, attrs, defAttrs, 13, 18);
attrs = { "font-family": kAbsentFontFamily };
testTextAttrs(ID, 18, attrs, defAttrs, 18, 22);
attrs = { };
testTextAttrs(ID, 22, attrs, defAttrs, 22, 27);
attrs = { "font-family": kCursiveFontFamily };
testTextAttrs(ID, 27, attrs, defAttrs, 27, 31);
attrs = { };
testTextAttrs(ID, 31, attrs, defAttrs, 31, 45);
SimpleTest.finish();
}
@ -417,6 +450,11 @@
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
title="Implement text attributes">
Mozilla Bug 345759
</a><br>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=473576"
title="font-family text attribute should expose actual font used">
Mozilla Bug 473576
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -469,7 +507,7 @@
<span style="font-size: 120%">bigger</span> smaller
<span style="background-color: blue;">background blue</span> normal
<span style="font-style: italic;">Different styling</span> normal
<span style="font-family: tahoma;">Different font</span> normal
<span style="font-family: monospace;">Different font</span> normal
<span style="text-decoration: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal
</p>
@ -478,7 +516,7 @@
<span style="font-size: 120%">bigger</span> smaller
<span style="background-color: blue;">background blue</span> normal
<span style="font-style: italic;">Different styling</span> normal
<span style="font-family: tahoma;">Different font</span> normal
<span style="font-family: monospace;">Different font</span> normal
<span style="text-decoration: underline;">underlined</span> normal
<span style="text-decoration: line-through;">strikethrough</span> normal
</p>
@ -500,5 +538,13 @@
<!-- *plain*plain**bold*bold*-->
<div id="area15"><p>embed</p>plain<p>embed</p>plain<p>embed</p><img src="../moz.png" alt="image"/><b>bold</b><p>embed</p><b>bold</b><p>embed</p></div>
<p id="area16" style="font-family: sans-serif;">
<span style="font-family: monospace;">text</span>text
<span style="font-family: serif;">text</span>text
<span style="font-family: BodoniThatDoesntExist;">text</span>text
<span style="font-family: Comic Sans MS, cursive;">text</span>text
<span style="font-family: sans-serif, fantasy;">text</span>text
</p>
</body>
</html>

View File

@ -49,7 +49,9 @@
this.finalCheck = function spelledTextInvoker_finalCheck()
{
var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize);
var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize,
kNormalFontWeight,
kInputFontFamily);
testDefaultTextAttrs(aID, defAttrs);
var attrs = { };

View File

@ -410,6 +410,10 @@ pref("dom.mozBrowserFramesWhitelist", "http://localhost:7777");
pref("dom.sms.enabled", true);
pref("dom.sms.whitelist", "file://,http://localhost:7777");
// Temporary permission hack for WebContacts
pref("dom.mozContacts.enabled", true);
pref("dom.mozContacts.whitelist", "http://localhost:7777");
// Ignore X-Frame-Options headers.
pref("b2g.ignoreXFrameOptions", true);

View File

@ -16,6 +16,7 @@ const LocalFile = CC('@mozilla.org/file/local;1',
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/ContactService.jsm');
XPCOMUtils.defineLazyGetter(Services, 'env', function() {
return Cc['@mozilla.org/process/environment;1']
@ -60,7 +61,7 @@ function startupHttpd(baseDir, port) {
// XXX never grant 'content-camera' to non-gaia apps
function addPermissions(urls) {
let permissions = [
'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'content-camera'
'indexedDB', 'indexedDB-unlimited', 'webapps-manage', 'offline-app', 'content-camera', 'webcontacts-manage'
];
urls.forEach(function(url) {
let uri = Services.io.newURI(url, null, null);

View File

@ -155,6 +155,7 @@
@BINPATH@/components/dom_bluetooth.xpt
#endif
@BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_contacts.xpt
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt
@BINPATH@/components/dom_events.xpt
@ -294,6 +295,8 @@
; JavaScript components
@BINPATH@/components/ConsoleAPI.manifest
@BINPATH@/components/ConsoleAPI.js
@BINPATH@/components/ContactManager.js
@BINPATH@/components/ContactManager.manifest
@BINPATH@/components/FeedProcessor.manifest
@BINPATH@/components/FeedProcessor.js
@BINPATH@/components/BrowserFeeds.manifest

View File

@ -1,7 +0,0 @@
richlistitem[type="tab"] {
-moz-binding: url(chrome://browser/content/aboutSyncTabs-bindings.xml#tab-listing);
}
richlistitem[type="client"] {
-moz-binding: url(chrome://browser/content/aboutSyncTabs-bindings.xml#client-listing);
}

View File

@ -101,25 +101,25 @@ var StarUI = {
this._restoreCommandsState();
this._itemId = -1;
if (this._batching) {
PlacesUIUtils.ptm.endBatch();
PlacesUtils.transactionManager.endBatch();
this._batching = false;
}
switch (this._actionOnHide) {
case "cancel": {
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
break;
}
case "remove": {
// Remove all bookmarks for the bookmark's url, this also removes
// the tags for the url.
PlacesUIUtils.ptm.beginBatch();
PlacesUtils.transactionManager.beginBatch();
let itemIds = PlacesUtils.getBookmarksForURI(this._uriForRemoval);
for (let i = 0; i < itemIds.length; i++) {
let txn = PlacesUIUtils.ptm.removeItem(itemIds[i]);
PlacesUIUtils.ptm.doTransaction(txn);
let txn = new PlacesRemoveItemTransaction(itemIds[i]);
PlacesUtils.transactionManager.doTransaction(txn);
}
PlacesUIUtils.ptm.endBatch();
PlacesUtils.transactionManager.endBatch();
break;
}
}
@ -275,7 +275,7 @@ var StarUI = {
beginBatch: function SU_beginBatch() {
if (!this._batching) {
PlacesUIUtils.ptm.beginBatch();
PlacesUtils.transactionManager.beginBatch();
this._batching = true;
}
}
@ -325,9 +325,10 @@ var PlacesCommandHook = {
var parent = aParent != undefined ?
aParent : PlacesUtils.unfiledBookmarksFolderId;
var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
var txn = PlacesUIUtils.ptm.createItem(uri, parent, -1,
title, null, [descAnno]);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesCreateBookmarkTransaction(uri, parent,
PlacesUtils.bookmarks.DEFAULT_INDEX,
title, null, [descAnno]);
PlacesUtils.transactionManager.doTransaction(txn);
// Set the character-set
if (charset)
PlacesUtils.history.setCharsetForURI(uri, charset);

View File

@ -291,7 +291,7 @@ let gSyncUI = {
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/syncSetup.xul",
window.openDialog("chrome://browser/content/sync/setup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no",
wizardType);
}
@ -305,7 +305,7 @@ let gSyncUI = {
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/syncAddDevice.xul",
window.openDialog("chrome://browser/content/sync/addDevice.xul",
"syncAddDevice", "centerscreen,chrome,resizable=no");
},
@ -315,7 +315,7 @@ let gSyncUI = {
win.focus();
else
Services.ww.activeWindow.openDialog(
"chrome://browser/content/syncQuota.xul", "",
"chrome://browser/content/sync/quota.xul", "",
"centerscreen,chrome,dialog,modal");
},

View File

@ -329,12 +329,12 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
%ifdef MOZ_SERVICES_SYNC
/* Sync notification UI */
#sync-notifications {
-moz-binding: url("chrome://browser/content/syncNotification.xml#notificationbox");
-moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox");
overflow-y: visible !important;
}
#sync-notifications notification {
-moz-binding: url("chrome://browser/content/syncNotification.xml#notification");
-moz-binding: url("chrome://browser/content/sync/notification.xml#notification");
}
%endif

View File

@ -1,3 +1,3 @@
<p><b>Binaries</b> of this product have been made available to you by the
<a href="http://www.mozilla.org/">Mozilla Project</a> under the Mozilla
Public License. <a href="about:rights">Know your rights</a>.</p>
Public License 2.0 (MPL). <a href="about:rights">Know your rights</a>.</p>

View File

@ -0,0 +1,7 @@
richlistitem[type="tab"] {
-moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#tab-listing);
}
richlistitem[type="client"] {
-moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#client-listing);
}

View File

@ -40,7 +40,7 @@
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/aboutSyncTabs.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/aboutSyncTabs.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/sync/aboutSyncTabs.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % aboutSyncTabsDTD SYSTEM "chrome://browser/locale/aboutSyncTabs.dtd">
@ -53,7 +53,7 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="&tabs.otherComputers.label;">
<script type="application/javascript;version=1.8" src="chrome://browser/content/aboutSyncTabs.js"/>
<script type="application/javascript;version=1.8" src="chrome://browser/content/sync/aboutSyncTabs.js"/>
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
<html:head>
<html:link rel="icon" href="chrome://browser/skin/sync-16.png"/>

View File

@ -61,9 +61,9 @@
onload="gSyncAddDevice.init();">
<script type="application/javascript"
src="chrome://browser/content/syncAddDevice.js"/>
src="chrome://browser/content/sync/addDevice.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
src="chrome://browser/content/sync/utils.js"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<script type="application/javascript"

View File

@ -60,9 +60,9 @@
onwizardfinish="return Change.onDialogAccept();">
<script type="application/javascript"
src="chrome://browser/content/syncGenericChange.js"/>
src="chrome://browser/content/sync/genericChange.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
src="chrome://browser/content/sync/utils.js"/>
<script type="application/javascript"
src="chrome://global/content/printUtils.js"/>

View File

@ -61,7 +61,7 @@
href="chrome://browser/skin/sync-16.png"/>
<script type="text/javascript;version=1.8"
src="chrome://browser/content/syncProgress.js"/>
src="chrome://browser/content/sync/progress.js"/>
</head>
<body onload="onLoad(event)" onunload="onUnload(event)">
<title>&setup.successPage.title;</title>

View File

@ -60,7 +60,7 @@
ondialogaccept="return gSyncQuota.onAccept();">
<script type="application/javascript"
src="chrome://browser/content/syncQuota.js"/>
src="chrome://browser/content/sync/quota.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="quotaStrings"

View File

@ -65,9 +65,9 @@
onload="gSyncSetup.init()">
<script type="application/javascript"
src="chrome://browser/content/syncSetup.js"/>
src="chrome://browser/content/sync/setup.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
src="chrome://browser/content/sync/utils.js"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<script type="application/javascript"

View File

@ -76,7 +76,7 @@ let gSyncUtils = {
}
// Open up the change dialog
let changeXUL = "chrome://browser/content/syncGenericChange.xul";
let changeXUL = "chrome://browser/content/sync/genericChange.xul";
let changeOpt = "centerscreen,chrome,resizable=no";
Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt,
type, duringSetup);
@ -125,7 +125,7 @@ let gSyncUtils = {
// Create an invisible iframe whose contents we can print.
let iframe = document.createElement("iframe");
iframe.setAttribute("src", "chrome://browser/content/syncKey.xhtml");
iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml");
iframe.collapsed = true;
document.documentElement.appendChild(iframe);
iframe.contentWindow.addEventListener("load", function() {

View File

@ -41,6 +41,25 @@ browser.jar:
* content/browser/pageinfo/feeds.xml (content/pageinfo/feeds.xml)
* content/browser/pageinfo/permissions.js (content/pageinfo/permissions.js)
* content/browser/pageinfo/security.js (content/pageinfo/security.js)
#ifdef MOZ_SERVICES_SYNC
* content/browser/sync/aboutSyncTabs.xul (content/sync/aboutSyncTabs.xul)
content/browser/sync/aboutSyncTabs.js (content/sync/aboutSyncTabs.js)
content/browser/sync/aboutSyncTabs.css (content/sync/aboutSyncTabs.css)
* content/browser/sync/aboutSyncTabs-bindings.xml (content/sync/aboutSyncTabs-bindings.xml)
* content/browser/sync/setup.xul (content/sync/setup.xul)
content/browser/sync/addDevice.js (content/sync/addDevice.js)
* content/browser/sync/addDevice.xul (content/sync/addDevice.xul)
content/browser/sync/setup.js (content/sync/setup.js)
* content/browser/sync/genericChange.xul (content/sync/genericChange.xul)
content/browser/sync/genericChange.js (content/sync/genericChange.js)
* content/browser/sync/key.xhtml (content/sync/key.xhtml)
* content/browser/sync/notification.xml (content/sync/notification.xml)
* content/browser/sync/quota.xul (content/sync/quota.xul)
content/browser/sync/quota.js (content/sync/quota.js)
content/browser/sync/utils.js (content/sync/utils.js)
content/browser/sync/progress.js (content/sync/progress.js)
* content/browser/sync/progress.xhtml (content/sync/progress.xhtml)
#endif
* content/browser/openLocation.js (content/openLocation.js)
* content/browser/openLocation.xul (content/openLocation.xul)
* content/browser/safeMode.js (content/safeMode.js)
@ -57,25 +76,6 @@ browser.jar:
* content/browser/web-panels.xul (content/web-panels.xul)
* content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul)
* content/browser/nsContextMenu.js (content/nsContextMenu.js)
#ifdef MOZ_SERVICES_SYNC
* content/browser/aboutSyncTabs.xul (content/aboutSyncTabs.xul)
content/browser/aboutSyncTabs.js (content/aboutSyncTabs.js)
content/browser/aboutSyncTabs.css (content/aboutSyncTabs.css)
* content/browser/aboutSyncTabs-bindings.xml (content/aboutSyncTabs-bindings.xml)
* content/browser/syncSetup.xul (content/syncSetup.xul)
content/browser/syncAddDevice.js (content/syncAddDevice.js)
* content/browser/syncAddDevice.xul (content/syncAddDevice.xul)
content/browser/syncSetup.js (content/syncSetup.js)
* content/browser/syncGenericChange.xul (content/syncGenericChange.xul)
content/browser/syncGenericChange.js (content/syncGenericChange.js)
* content/browser/syncKey.xhtml (content/syncKey.xhtml)
* content/browser/syncNotification.xml (content/syncNotification.xml)
* content/browser/syncQuota.xul (content/syncQuota.xul)
content/browser/syncQuota.js (content/syncQuota.js)
content/browser/syncUtils.js (content/syncUtils.js)
content/browser/syncProgress.js (content/syncProgress.js)
* content/browser/syncProgress.xhtml (content/syncProgress.xhtml)
#endif
# XXX: We should exclude this one as well (bug 71895)
* content/browser/hiddenWindow.xul (content/hiddenWindow.xul)
#ifdef XP_MACOSX

View File

@ -97,9 +97,9 @@ static RedirEntry kRedirMap[] = {
{ "sessionrestore", "chrome://browser/content/aboutSessionRestore.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
#ifdef MOZ_SERVICES_SYNC
{ "sync-progress", "chrome://browser/content/syncProgress.xhtml",
{ "sync-progress", "chrome://browser/content/sync/progress.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
{ "sync-tabs", "chrome://browser/content/aboutSyncTabs.xul",
{ "sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul",
nsIAboutModule::ALLOW_SCRIPT },
#endif
{ "home", "chrome://browser/content/aboutHome.xhtml",

View File

@ -1,3 +1,4 @@
# -*- indent-tabs-mode: nil -*-
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
@ -774,18 +775,71 @@ BrowserGlue.prototype = {
const PREF_TELEMETRY_REJECTED = "toolkit.telemetry.rejected";
const PREF_TELEMETRY_INFOURL = "toolkit.telemetry.infoURL";
const PREF_TELEMETRY_SERVER_OWNER = "toolkit.telemetry.server_owner";
const PREF_TELEMETRY_ENABLED_BY_DEFAULT = "toolkit.telemetry.enabledByDefault";
const PREF_TELEMETRY_NOTIFIED_OPTOUT = "toolkit.telemetry.notifiedOptOut";
// This is used to reprompt users when privacy message changes
const TELEMETRY_PROMPT_REV = 2;
function appendTelemetryNotification(notifyBox, message, buttons, hideclose) {
// Stick notifications onto the selected tab of the active browser window.
var win = this.getMostRecentBrowserWindow();
var tabbrowser = win.gBrowser;
var notifyBox = tabbrowser.getNotificationBox();
var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
var productName = brandBundle.GetStringFromName("brandFullName");
var serverOwner = Services.prefs.getCharPref(PREF_TELEMETRY_SERVER_OWNER);
function appendTelemetryNotification(message, buttons, hideclose) {
let notification = notifyBox.appendNotification(message, "telemetry", null,
notifyBox.PRIORITY_INFO_LOW,
buttons);
notification.setAttribute("hideclose", hideclose);
notifyBox.PRIORITY_INFO_LOW,
buttons);
if (hideclose)
notification.setAttribute("hideclose", hideclose);
notification.persistence = -1; // Until user closes it
return notification;
}
function appendLearnMoreLink(notification) {
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let link = notification.ownerDocument.createElementNS(XULNS, "label");
link.className = "text-link telemetry-text-link";
link.setAttribute("value", browserBundle.GetStringFromName("telemetryLinkLabel"));
let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
description.appendChild(link);
return link;
}
var telemetryEnabledByDefault = false;
try {
telemetryEnabledByDefault = Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED_BY_DEFAULT);
} catch(e) {}
if (telemetryEnabledByDefault) {
var telemetryNotifiedOptOut = false;
try {
telemetryNotifiedOptOut = Services.prefs.getBoolPref(PREF_TELEMETRY_NOTIFIED_OPTOUT);
} catch(e) {}
if (telemetryNotifiedOptOut)
return;
var telemetryPrompt = browserBundle.formatStringFromName("telemetryOptOutPrompt",
[productName, serverOwner, productName], 3);
Services.prefs.setBoolPref(PREF_TELEMETRY_NOTIFIED_OPTOUT, true);
let notification = appendTelemetryNotification(telemetryPrompt, null, false);
let link = appendLearnMoreLink(notification);
link.addEventListener('click', function() {
// Open the learn more url in a new tab
let url = Services.urlFormatter.formatURLPref("app.support.baseURL");
url += "how-can-i-help-submitting-performance-data";
tabbrowser.selectedTab = tabbrowser.addTab(url);
// Remove the notification on which the user clicked
notification.parentNode.removeNotification(notification, true);
}, false);
return;
}
var telemetryPrompted = null;
try {
telemetryPrompted = Services.prefs.getIntPref(PREF_TELEMETRY_PROMPTED);
@ -798,17 +852,7 @@ BrowserGlue.prototype = {
Services.prefs.clearUserPref(PREF_TELEMETRY_PROMPTED);
Services.prefs.clearUserPref(PREF_TELEMETRY_ENABLED);
// Stick the notification onto the selected tab of the active browser window.
var win = this.getMostRecentBrowserWindow();
var browser = win.gBrowser; // for closure in notification bar callback
var notifyBox = browser.getNotificationBox();
var browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
var productName = brandBundle.GetStringFromName("brandFullName");
var serverOwner = Services.prefs.getCharPref(PREF_TELEMETRY_SERVER_OWNER);
var telemetryPrompt = browserBundle.formatStringFromName("telemetryPrompt", [productName, serverOwner], 2);
var telemetryPrompt = browserBundle.formatStringFromName("telemetryPrompt", [productName, serverOwner], 2);
var buttons = [
{
@ -832,23 +876,17 @@ BrowserGlue.prototype = {
// Set pref to indicate we've shown the notification.
Services.prefs.setIntPref(PREF_TELEMETRY_PROMPTED, TELEMETRY_PROMPT_REV);
let notification = appendTelemetryNotification(notifyBox, telemetryPrompt,
buttons, true);
let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let link = notification.ownerDocument.createElementNS(XULNS, "label");
link.className = "text-link telemetry-text-link";
link.setAttribute("value", browserBundle.GetStringFromName("telemetryLinkLabel"));
let notification = appendTelemetryNotification(telemetryPrompt, buttons, true);
let link = appendLearnMoreLink(notification);
link.addEventListener('click', function() {
// Open the learn more url in a new tab
browser.selectedTab = browser.addTab(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL));
tabbrowser.selectedTab = tabbrowser.addTab(Services.prefs.getCharPref(PREF_TELEMETRY_INFOURL));
// Remove the notification on which the user clicked
notification.parentNode.removeNotification(notification, true);
// Add a new notification to that tab, with no "Learn more" link
notifyBox = browser.getNotificationBox();
appendTelemetryNotification(notifyBox, telemetryPrompt, buttons, true);
notifyBox = tabbrowser.getNotificationBox();
appendTelemetryNotification(telemetryPrompt, buttons, true);
}, false);
let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText");
description.appendChild(link);
},
#endif

View File

@ -436,7 +436,7 @@ var BookmarkPropertiesPanel = {
if (this._batching)
return;
PlacesUIUtils.ptm.beginBatch();
PlacesUtils.transactionManager.beginBatch();
this._batching = true;
},
@ -444,7 +444,7 @@ var BookmarkPropertiesPanel = {
if (!this._batching)
return;
PlacesUIUtils.ptm.endBatch();
PlacesUtils.transactionManager.endBatch();
this._batching = false;
},
@ -514,7 +514,7 @@ var BookmarkPropertiesPanel = {
gEditItemOverlay.uninitPanel(true);
gEditItemOverlay = null;
this._endBatch();
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
window.arguments[0].performed = false;
},
@ -577,32 +577,44 @@ var BookmarkPropertiesPanel = {
var childTransactions = [];
if (this._description) {
childTransactions.push(
PlacesUIUtils.ptm.editItemDescription(-1, this._description));
let annoObj = { name : PlacesUIUtils.DESCRIPTION_ANNO,
type : Ci.nsIAnnotationService.TYPE_STRING,
flags : 0,
value : this._description,
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
let editItemTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
childTransactions.push(editItemTxn);
}
if (this._loadInSidebar) {
childTransactions.push(
PlacesUIUtils.ptm.setLoadInSidebar(-1, this._loadInSidebar));
let annoObj = { name : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
type : Ci.nsIAnnotationService.TYPE_INT32,
flags : 0,
value : this._loadInSidebar,
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
let setLoadTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
childTransactions.push(setLoadTxn);
}
if (this._postData) {
childTransactions.push(
PlacesUIUtils.ptm.editBookmarkPostData(-1, this._postData));
let postDataTxn = new PlacesEditBookmarkPostDataTransaction(-1, this._postData);
childTransactions.push(postDataTxn);
}
//XXX TODO: this should be in a transaction!
if (this._charSet)
PlacesUtils.history.setCharsetForURI(this._uri, this._charSet);
var transactions = [PlacesUIUtils.ptm.createItem(this._uri,
aContainer, aIndex,
this._title, this._keyword,
annotations,
childTransactions)];
let createTxn = new PlacesCreateBookmarkTransaction(this._uri,
aContainer,
aIndex,
this._title,
this._keyword,
annotations,
childTransactions);
return PlacesUIUtils.ptm.aggregateTransactions(this._getDialogTitle(),
transactions);
return new PlacesAggregatedTransaction(this._getDialogTitle(),
[createTxn]);
},
/**
@ -614,7 +626,10 @@ var BookmarkPropertiesPanel = {
for (var i = 0; i < this._URIs.length; ++i) {
var uri = this._URIs[i];
var title = this._getURITitleFromHistory(uri);
transactions.push(PlacesUIUtils.ptm.createItem(uri, -1, -1, title));
var createTxn = new PlacesCreateBookmarkTransaction(uri, -1,
PlacesUtils.bookmarks.DEFAULT_INDEX,
title);
transactions.push(createTxn);
}
return transactions;
},
@ -633,8 +648,9 @@ var BookmarkPropertiesPanel = {
if (this._description)
annotations.push(this._getDescriptionAnnotation(this._description));
return PlacesUIUtils.ptm.createFolder(this._title, aContainer, aIndex,
annotations, childItemsTransactions);
return new PlacesCreateFolderTransaction(this._title, aContainer,
aIndex, annotations,
childItemsTransactions);
},
/**
@ -643,9 +659,9 @@ var BookmarkPropertiesPanel = {
*/
_getCreateNewLivemarkTransaction:
function BPP__getCreateNewLivemarkTransaction(aContainer, aIndex) {
return PlacesUIUtils.ptm.createLivemark(this._feedURI, this._siteURI,
this._title,
aContainer, aIndex);
return new PlacesCreateLivemarkTransaction(this._feedURI, this._siteURI,
this._title,
aContainer, aIndex);
},
/**
@ -666,7 +682,7 @@ var BookmarkPropertiesPanel = {
txn = this._getCreateNewBookmarkTransaction(container, index);
}
PlacesUIUtils.ptm.doTransaction(txn);
PlacesUtils.transactionManager.doTransaction(txn);
this._itemId = PlacesUtils.bookmarks.getIdForItemAt(container, index);
}
};

View File

@ -1858,13 +1858,16 @@ PlacesMenu.prototype = {
_onPopupHidden: function PM__onPopupHidden(aEvent) {
// Avoid handling popuphidden of inner views.
let popup = aEvent.originalTarget;
if (!popup._placesNode || PlacesUIUtils.getViewForNode(popup) != this)
let placesNode = popup._placesNode;
if (!placesNode || PlacesUIUtils.getViewForNode(popup) != this)
return;
// UI performance: folder queries are cheap, keep the resultnode open
// so we don't rebuild its contents whenever the popup is reopened.
if (!PlacesUtils.nodeIsFolder(popup._placesNode))
popup._placesNode.containerOpen = false;
// Though, we want to always close feed containers so their expiration
// status will be checked at next opening.
if (!PlacesUtils.nodeIsFolder(placesNode) || placesNode._feedURI)
placesNode.containerOpen = false;
// The autoopened attribute is set for folders which have been
// automatically opened when dragged over. Turn off this attribute

View File

@ -157,9 +157,9 @@ PlacesController.prototype = {
isCommandEnabled: function PC_isCommandEnabled(aCommand) {
switch (aCommand) {
case "cmd_undo":
return PlacesUIUtils.ptm.numberOfUndoItems > 0;
return PlacesUtils.transactionManager.numberOfUndoItems > 0;
case "cmd_redo":
return PlacesUIUtils.ptm.numberOfRedoItems > 0;
return PlacesUtils.transactionManager.numberOfRedoItems > 0;
case "cmd_cut":
case "placesCmd_cut":
var nodes = this._view.selectedNodes;
@ -230,10 +230,10 @@ PlacesController.prototype = {
doCommand: function PC_doCommand(aCommand) {
switch (aCommand) {
case "cmd_undo":
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
break;
case "cmd_redo":
PlacesUIUtils.ptm.redoTransaction();
PlacesUtils.transactionManager.redoTransaction();
break;
case "cmd_cut":
case "placesCmd_cut":
@ -785,8 +785,8 @@ PlacesController.prototype = {
var ip = this._view.insertionPoint;
if (!ip)
throw Cr.NS_ERROR_NOT_AVAILABLE;
var txn = PlacesUIUtils.ptm.createSeparator(ip.itemId, ip.index);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesCreateSeparatorTransaction(ip.itemId, ip.index);
PlacesUtils.transactionManager.doTransaction(txn);
// select the new item
var insertedNodeId = PlacesUtils.bookmarks
.getIdForItemAt(ip.itemId, ip.index);
@ -807,8 +807,8 @@ PlacesController.prototype = {
*/
sortFolderByName: function PC_sortFolderByName() {
var itemId = PlacesUtils.getConcreteItemId(this._view.selectedNode);
var txn = PlacesUIUtils.ptm.sortFolderByName(itemId);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesSortFolderByNameTransaction(itemId);
PlacesUtils.transactionManager.doTransaction(txn);
},
/**
@ -872,7 +872,8 @@ PlacesController.prototype = {
// untag transaction.
var tagItemId = PlacesUtils.getConcreteItemId(node.parent);
var uri = NetUtil.newURI(node.uri);
transactions.push(PlacesUIUtils.ptm.untagURI(uri, [tagItemId]));
let txn = new PlacesUntagURITransaction(uri, [tagItemId]);
transactions.push(txn);
}
else if (PlacesUtils.nodeIsTagQuery(node) && node.parent &&
PlacesUtils.nodeIsQuery(node.parent) &&
@ -884,8 +885,10 @@ PlacesController.prototype = {
// must only remove the query node.
var tag = node.title;
var URIs = PlacesUtils.tagging.getURIsForTag(tag);
for (var j = 0; j < URIs.length; j++)
transactions.push(PlacesUIUtils.ptm.untagURI(URIs[j], [tag]));
for (var j = 0; j < URIs.length; j++) {
let txn = new PlacesUntagURITransaction(URIs[j], [tag]);
transactions.push(txn);
}
}
else if (PlacesUtils.nodeIsURI(node) &&
PlacesUtils.nodeIsQuery(node.parent) &&
@ -912,7 +915,8 @@ PlacesController.prototype = {
// to skip nodes that are children of an already removed folder.
removedFolders.push(node);
}
transactions.push(PlacesUIUtils.ptm.removeItem(node.itemId));
let txn = new PlacesRemoveItemTransaction(node.itemId);
transactions.push(txn);
}
}
},
@ -931,8 +935,8 @@ PlacesController.prototype = {
this._removeRange(ranges[i], transactions, removedFolders);
if (transactions.length > 0) {
var txn = PlacesUIUtils.ptm.aggregateTransactions(txnName, transactions);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesAggregatedTransaction(txnName, transactions);
PlacesUtils.transactionManager.doTransaction(txn);
}
},
@ -1278,10 +1282,9 @@ PlacesController.prototype = {
if (ip.isTag) {
// Pasting into a tag container means tagging the item, regardless of
// the requested action.
transactions.push(
new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
[ip.itemId])
);
let tagTxn = new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
[ip.itemId]);
transactions.push(tagTxn);
continue;
}
@ -1296,9 +1299,8 @@ PlacesController.prototype = {
);
}
PlacesUtils.transactionManager.doTransaction(
new PlacesAggregatedTransaction("Paste", transactions)
);
let aggregatedTxn = new PlacesAggregatedTransaction("Paste", transactions);
PlacesUtils.transactionManager.doTransaction(aggregatedTxn);
// Cut/past operations are not repeatable, so clear the clipboard.
if (action == "cut") {
@ -1548,7 +1550,8 @@ let PlacesControllerDragHelper = {
insertionPoint.orientation == Ci.nsITreeView.DROP_ON) {
let uri = NetUtil.newURI(unwrapped.uri);
let tagItemId = insertionPoint.itemId;
transactions.push(PlacesUIUtils.ptm.tagURI(uri,[tagItemId]));
let tagTxn = new PlacesTagURITransaction(uri, [tagItemId]);
transactions.push(tagTxn);
}
else {
transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
@ -1557,8 +1560,8 @@ let PlacesControllerDragHelper = {
}
}
let txn = PlacesUIUtils.ptm.aggregateTransactions("DropItems", transactions);
PlacesUIUtils.ptm.doTransaction(txn);
let txn = new PlacesAggregatedTransaction("DropItems", transactions);
PlacesUtils.transactionManager.doTransaction(txn);
},
/**

View File

@ -435,15 +435,18 @@ var gEditItemOverlay = {
tagsToAdd.push(tags[i]);
}
if (tagsToRemove.length > 0)
txns.push(PlacesUIUtils.ptm.untagURI(this._uri, tagsToRemove));
if (tagsToAdd.length > 0)
txns.push(PlacesUIUtils.ptm.tagURI(this._uri, tagsToAdd));
if (tagsToRemove.length > 0) {
let untagTxn = new PlacesUntagURITransaction(this._uri, tagsToRemove);
txns.push(untagTxn);
}
if (tagsToAdd.length > 0) {
let tagTxn = new PlacesTagURITransaction(this._uri, tagsToAdd);
txns.push(tagTxn);
}
if (txns.length > 0) {
var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update tags",
txns);
PlacesUIUtils.ptm.doTransaction(aggregate);
let aggregate = new PlacesAggregatedTransaction("Update tags", txns);
PlacesUtils.transactionManager.doTransaction(aggregate);
// Ensure the tagsField is in sync, clean it up from empty tags
var tags = PlacesUtils.tagging.getTagsForURI(this._uri).join(", ");
@ -495,25 +498,31 @@ var gEditItemOverlay = {
}
if (tagsToAdd.length > 0) {
for (i = 0; i < this._uris.length; i++) {
if (tagsToAdd[i].length > 0)
txns.push(PlacesUIUtils.ptm.tagURI(this._uris[i], tagsToAdd[i]));
for (let i = 0; i < this._uris.length; i++) {
if (tagsToAdd[i].length > 0) {
let tagTxn = new PlacesTagURITransaction(this._uris[i],
tagsToAdd[i]);
txns.push(tagTxn);
}
}
}
if (tagsToRemove.length > 0) {
for (var i = 0; i < this._uris.length; i++)
txns.push(PlacesUIUtils.ptm.untagURI(this._uris[i], tagsToRemove));
for (let i = 0; i < this._uris.length; i++) {
let untagTxn = new PlacesUntagURITransaction(this._uris[i],
tagsToRemove);
txns.push(untagTxn);
}
}
if (txns.length > 0) {
var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update tags",
txns);
PlacesUIUtils.ptm.doTransaction(aggregate);
let aggregate = new PlacesAggregatedTransaction("Update tags", txns);
PlacesUtils.transactionManager.doTransaction(aggregate);
this._allTags = tags;
this._tags = [];
for (i = 0; i < this._uris.length; i++)
for (let i = 0; i < this._uris.length; i++) {
this._tags[i] = PlacesUtils.tagging.getTagsForURI(this._uris[i]);
}
// Ensure the tagsField is in sync, clean it up from empty tags
this._initTextField("tagsField", tags, false);
@ -528,8 +537,6 @@ var gEditItemOverlay = {
return;
var namePicker = this._element("namePicker")
var txns = [];
const ptm = PlacesUIUtils.ptm;
// Here we update either the item title or its cached static title
var newTitle = namePicker.value;
@ -540,19 +547,21 @@ var gEditItemOverlay = {
}
else if (this._getItemStaticTitle() != newTitle) {
this._mayUpdateFirstEditField("namePicker");
txns.push(ptm.editItemTitle(this._itemId, newTitle));
let txn = new PlacesEditItemTitleTransaction(this._itemId, newTitle);
PlacesUtils.transactionManager.doTransaction(txn);
}
var aggregate = ptm.aggregateTransactions("Edit Item Title", txns);
ptm.doTransaction(aggregate);
},
onDescriptionFieldBlur: function EIO_onDescriptionFieldBlur() {
var description = this._element("descriptionField").value;
if (description != PlacesUIUtils.getItemDescription(this._itemId)) {
var txn = PlacesUIUtils.ptm
.editItemDescription(this._itemId, description);
PlacesUIUtils.ptm.doTransaction(txn);
var annoObj = { name : PlacesUIUtils.DESCRIPTION_ANNO,
type : Ci.nsIAnnotationService.TYPE_STRING,
flags : 0,
value : description,
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
var txn = new PlacesSetItemAnnotationTransaction(this._itemId, annoObj);
PlacesUtils.transactionManager.doTransaction(txn);
}
},
@ -564,8 +573,8 @@ var gEditItemOverlay = {
catch(ex) { return; }
if (!this._uri.equals(uri)) {
var txn = PlacesUIUtils.ptm.editBookmarkURI(this._itemId, uri);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesEditBookmarkURITransaction(this._itemId, uri);
PlacesUtils.transactionManager.doTransaction(txn);
this._uri = uri;
}
},
@ -573,17 +582,22 @@ var gEditItemOverlay = {
onKeywordFieldBlur: function EIO_onKeywordFieldBlur() {
var keyword = this._element("keywordField").value;
if (keyword != PlacesUtils.bookmarks.getKeywordForBookmark(this._itemId)) {
var txn = PlacesUIUtils.ptm.editBookmarkKeyword(this._itemId, keyword);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesEditBookmarkKeywordTransaction(this._itemId, keyword);
PlacesUtils.transactionManager.doTransaction(txn);
}
},
onLoadInSidebarCheckboxCommand:
function EIO_onLoadInSidebarCheckboxCommand() {
var loadInSidebarChecked = this._element("loadInSidebarCheckbox").checked;
var txn = PlacesUIUtils.ptm.setLoadInSidebar(this._itemId,
loadInSidebarChecked);
PlacesUIUtils.ptm.doTransaction(txn);
var annoObj = { name : PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
type : Ci.nsIAnnotationService.TYPE_INT32,
flags : 0,
value : loadInSidebarChecked,
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
var txn = new PlacesSetItemAnnotationTransaction(this._itemId,
annoObj);
PlacesUtils.transactionManager.doTransaction(txn);
},
toggleFolderTreeVisibility: function EIO_toggleFolderTreeVisibility() {
@ -672,8 +686,10 @@ var gEditItemOverlay = {
// Move the item
var container = this._getFolderIdFromMenuList();
if (PlacesUtils.bookmarks.getFolderIdForItem(this._itemId) != container) {
var txn = PlacesUIUtils.ptm.moveItem(this._itemId, container, -1);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesMoveItemTransaction(this._itemId,
container,
PlacesUtils.bookmarks.DEFAULT_INDEX);
PlacesUtils.transactionManager.doTransaction(txn);
// Mark the containing folder as recently-used if it isn't in the
// static list
@ -720,15 +736,17 @@ var gEditItemOverlay = {
var anno = this._getLastUsedAnnotationObject(false);
while (this._recentFolders.length > MAX_FOLDER_ITEM_IN_MENU_LIST) {
var folderId = this._recentFolders.pop().folderId;
txns.push(PlacesUIUtils.ptm.setItemAnnotation(folderId, anno));
let annoTxn = new PlacesSetItemAnnotationTransaction(folderId, anno);
txns.push(annoTxn);
}
// Mark folder as recently used
anno = this._getLastUsedAnnotationObject(true);
txns.push(PlacesUIUtils.ptm.setItemAnnotation(aFolderId, anno));
let annoTxn = new PlacesSetItemAnnotationTransaction(aFolderId, anno);
txns.push(annoTxn);
var aggregate = PlacesUIUtils.ptm.aggregateTransactions("Update last used folders", txns);
PlacesUIUtils.ptm.doTransaction(aggregate);
let aggregate = new PlacesAggregatedTransaction("Update last used folders", txns);
PlacesUtils.transactionManager.doTransaction(aggregate);
},
/**
@ -840,8 +858,8 @@ var gEditItemOverlay = {
// XXXmano: add a separate "New Folder" string at some point...
var defaultLabel = this._element("newFolderButton").label;
var txn = PlacesUIUtils.ptm.createFolder(defaultLabel, ip.itemId, ip.index);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesCreateFolderTransaction(defaultLabel, ip.itemId, ip.index);
PlacesUtils.transactionManager.doTransaction(txn);
this._folderTree.focus();
this._folderTree.selectItems([this._lastNewItem]);
this._folderTree.startEditing(this._folderTree.view.selection.currentIndex,

View File

@ -67,13 +67,15 @@ var gMoveBookmarksDialog = {
if (this._nodes[i].parent.itemId == selectedFolderID)
continue;
transactions.push(new
PlacesUIUtils.ptm.moveItem(this._nodes[i].itemId, selectedFolderID, -1));
let txn = new PlacesMoveItemTransaction(this._nodes[i].itemId,
selectedFolderID,
PlacesUtils.bookmarks.DEFAULT_INDEX);
transactions.push(txn);
}
if (transactions.length != 0) {
var txn = PlacesUIUtils.ptm.aggregateTransactions("Move Items", transactions);
PlacesUIUtils.ptm.doTransaction(txn);
let txn = new PlacesAggregatedTransaction("Move Items", transactions);
PlacesUtils.transactionManager.doTransaction(txn);
}
},

View File

@ -828,11 +828,11 @@ var PlacesOrganizer = {
return;
// Add the place: uri as a bookmark under the bookmarks root.
var txn = PlacesUIUtils.ptm.createItem(placeURI,
PlacesUtils.bookmarksMenuFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX,
input.value);
PlacesUIUtils.ptm.doTransaction(txn);
var txn = new PlacesCreateBookmarkTransaction(placeURI,
PlacesUtils.bookmarksMenuFolderId,
PlacesUtils.bookmarks.DEFAULT_INDEX,
input.value);
PlacesUtils.transactionManager.doTransaction(txn);
// select and load the new query
this._places.selectPlaceURI(placeSpec);

View File

@ -1660,8 +1660,8 @@ PlacesTreeView.prototype = {
// We may only get here if the cell is editable.
let node = this._rows[aRow];
if (node.title != aText) {
let txn = PlacesUIUtils.ptm.editItemTitle(node.itemId, aText);
PlacesUIUtils.ptm.doTransaction(txn);
let txn = new PlacesEditItemTitleTransaction(node.itemId, aText);
PlacesUtils.transactionManager.doTransaction(txn);
}
},

View File

@ -86,7 +86,7 @@ function test() {
-1,
true);
ok(transaction, "create transaction");
PlacesUIUtils.ptm.doTransaction(transaction);
PlacesUtils.transactionManager.doTransaction(transaction);
// confirm copy
is(testRootNode.childCount, 2, "create test folder via copy");
@ -95,11 +95,11 @@ function test() {
validate(folderBNode);
// undo the transaction, confirm the removal
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
// redo the transaction
PlacesUIUtils.ptm.redoTransaction();
PlacesUtils.transactionManager.redoTransaction();
is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
folderBNode = testRootNode.getChild(1);
validate(folderBNode);
@ -109,7 +109,7 @@ function test() {
toolbarNode.containerOpen = false;
// clean up
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
PlacesUtils.bookmarks.removeItem(folderAId);
}

View File

@ -85,7 +85,7 @@ function test() {
ok(transaction, "create transaction");
// execute it, copying to the test root folder
PlacesUIUtils.ptm.doTransaction(transaction);
PlacesUtils.transactionManager.doTransaction(transaction);
is(testRootNode.childCount, 2, "create test folder via copy");
// check GUIDs are different
@ -95,12 +95,12 @@ function test() {
ok(checkGUIDs(folderBNode, folderBGUIDs, true), "confirm test of new GUIDs");
// undo the transaction, confirm the removal
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
// redo the transaction
// confirming GUIDs persist through undo/redo
PlacesUIUtils.ptm.redoTransaction();
PlacesUtils.transactionManager.redoTransaction();
is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
folderBNode = testRootNode.getChild(1);
ok(checkGUIDs(folderBNode, folderAGUIDs, false), "folder B GUIDs after undo/redo don't match folder A GUIDs"); // sanity check
@ -111,7 +111,7 @@ function test() {
toolbarNode.containerOpen = false;
// clean up
PlacesUIUtils.ptm.undoTransaction();
PlacesUtils.transactionManager.undoTransaction();
PlacesUtils.bookmarks.removeItem(testRootId);
}

View File

@ -19,6 +19,4 @@ tail =
[test_browserGlue_smartBookmarks.js]
[test_clearHistory_shutdown.js]
[test_leftpane_corruption_handling.js]
[test_placesTxn.js]
[test_PUIU_makeTransaction.js]
[test_txnGUIDs.js]

View File

@ -157,7 +157,7 @@ let gSyncPane = {
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/syncSetup.xul",
window.openDialog("chrome://browser/content/sync/setup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no",
wizardType);
}
@ -168,7 +168,7 @@ let gSyncPane = {
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/syncQuota.xul", "",
window.openDialog("chrome://browser/content/sync/quota.xul", "",
"centerscreen,chrome,dialog,modal");
},
@ -180,7 +180,7 @@ let gSyncPane = {
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/syncAddDevice.xul",
window.openDialog("chrome://browser/content/sync/addDevice.xul",
"syncAddDevice", "centerscreen,chrome,resizable=no");
},

View File

@ -69,7 +69,7 @@
<script type="application/javascript"
src="chrome://browser/content/preferences/sync.js"/>
<script type="application/javascript"
src="chrome://browser/content/syncUtils.js"/>
src="chrome://browser/content/sync/utils.js"/>
<deck id="weavePrefsDeck">

View File

@ -42,8 +42,8 @@ MOZ_UPDATER=1
MOZ_PHOENIX=1
if test "$OS_ARCH" = "WINNT"; then
MOZ_VERIFY_MAR_SIGNATURE=1
if ! test "$HAVE_64BIT_OS"; then
MOZ_VERIFY_MAR_SIGNATURE=1
MOZ_MAINTENANCE_SERVICE=1
fi
fi
@ -54,8 +54,13 @@ MOZ_SERVICES_SYNC=1
MOZ_APP_VERSION=$FIREFOX_VERSION
MOZ_EXTENSIONS_DEFAULT=" gnomevfs"
# MOZ_APP_DISPLAYNAME will be set by branding/configure.sh
# Changing either of these values requires a clobber to ensure correct results,
# Changing MOZ_*BRANDING_DIRECTORY requires a clobber to ensure correct results,
# because branding dependencies are broken.
# MOZ_BRANDING_DIRECTORY is the default branding directory used when none is
# specified. It should never point to the "official" branding directory.
# For mozilla-beta, mozilla-release, or mozilla-central repositories, use
# "nightly" branding (until bug 659568 is fixed).
# For the mozilla-aurora repository, use "aurora".
MOZ_BRANDING_DIRECTORY=browser/branding/nightly
MOZ_OFFICIAL_BRANDING_DIRECTORY=browser/branding/official
MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}

View File

@ -155,6 +155,7 @@
@BINPATH@/components/dom_bluetooth.xpt
#endif
@BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_contacts.xpt
@BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt
@BINPATH@/components/dom_events.xpt
@ -409,6 +410,9 @@
@BINPATH@/components/messageWakeupService.js
@BINPATH@/components/messageWakeupService.manifest
@BINPATH@/components/ContactManager.js
@BINPATH@/components/ContactManager.manifest
; Modules
@BINPATH@/modules/*

View File

@ -333,3 +333,7 @@ telemetryYesButtonLabel2 = Yes, I want to help
telemetryYesButtonAccessKey = Y
telemetryNoButtonLabel = No
telemetryNoButtonAccessKey = 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.
telemetryOptOutPrompt = %1$S sends information about performance, hardware, usage and customizations back to %2$S to help improve %3$S.

View File

@ -1,4 +1,4 @@
/* The following are used by both syncSetup.xul and syncGenericChange.xul */
/* The following are used by both sync/setup.xul and sync/genericChange.xul */
.status {
color: -moz-dialogtext;
}
@ -21,7 +21,7 @@
list-style-image: url("moz-icon://stock/gtk-dialog-info?size=menu");
}
/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
a separate stylesheet for it. */
.data {
font-size: 90%;

View File

@ -1,4 +1,4 @@
/* The following are used by both syncSetup.xul and syncGenericChange.xul */
/* The following are used by both sync/setup.xul and sync/genericChange.xul */
.status {
color: -moz-dialogtext;
}
@ -21,7 +21,7 @@
list-style-image: url("chrome://global/skin/icons/information-16.png");
}
/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
a separate stylesheet for it. */
.data {
font-size: 90%;

View File

@ -1,4 +1,4 @@
/* The following are used by both syncSetup.xul and syncGenericChange.xul */
/* The following are used by both sync/setup.xul and sync/genericChange.xul */
.status {
color: -moz-dialogtext;
}
@ -21,7 +21,7 @@
list-style-image: url("chrome://global/skin/icons/information-16.png");
}
/* .data is only used by syncGenericChange.xul, but it seems unnecessary to have
/* .data is only used by sync/genericChange.xul, but it seems unnecessary to have
a separate stylesheet for it. */
.data {
font-size: 90%;

View File

@ -1,89 +0,0 @@
# ***** 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 remote test framework.
#
# The Initial Developer of the Original Code is
# the Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# 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 *****
import devicemanager
import devicemanagerUtils
import sys
import os
def main():
ip_addr = os.environ.get("DEVICE_IP")
port = os.environ.get("DEVICE_PORT")
gre_path = os.environ.get("REMOTE_GRE_PATH").replace('\\','/')
if ip_addr == None:
print "Error: please define the environment variable DEVICE_IP before running this test"
sys.exit(1)
if port == None:
print "Error: please define the environment variable DEVICE_PORT before running this test"
sys.exit(1)
if gre_path == None:
print "Error: please define the environment variable REMOTE_GRE_PATH before running this test"
sys.exit(1)
dm = devicemanagerUtils.getDeviceManager(ip_addr, int(port))
if len(sys.argv) < 2:
print "usage python devicemanager-run-test.py <test program> [args1 [arg2..]]"
sys.exit(1)
cmd = sys.argv[1]
args = ' '
if len(sys.argv) > 2:
args = ' ' + ' '.join(sys.argv[2:])
dm.debug = 0
lastslash = cmd.rfind('/');
if lastslash == -1:
lastslash = 0
dm.pushFile(cmd, gre_path + cmd[lastslash:])
process = dm.launchProcess([gre_path + cmd[lastslash:] + args])
output_list = dm.communicate(process)
ret = -1
if (output_list != None and output_list[0] != None):
try:
output = output_list[0]
index = output.find('exited with return code')
print output[0:index]
retstr = (output[index + 24 : output.find('\n', index)])
ret = int(retstr)
except ValueError:
ret = -1
sys.exit(ret)
if __name__ == '__main__':
main()

View File

@ -197,31 +197,6 @@ class DeviceManager:
failure: None
"""
def communicate(self, process, timeout = 600, interval = 5):
"""
loops until 'process' has exited or 'timeout' seconds is reached
loop sleeps for 'interval' seconds between iterations
external function
returns:
success: [file contents, None]
failure: [None, None]
"""
timed_out = True
if (timeout > 0):
total_time = 0
while total_time < timeout:
time.sleep(interval)
if self.processExist(process) == None:
timed_out = False
break
total_time += interval
if (timed_out == True):
return [None, None]
return [self.getFile(process, "temp.txt"), None]
def processExist(self, appname):
"""
iterates process list and returns pid if exists, otherwise None
@ -601,14 +576,14 @@ def _pop_last_line(file):
bytes_from_end = 1
file.seek(0, 2)
length = file.tell() + 1
while bytes_from_end <= length:
while bytes_from_end < length:
file.seek((-1)*bytes_from_end, 2)
data = file.read()
if bytes_from_end == length and len(data) == 0: # no data, return None
if bytes_from_end == length-1 and len(data) == 0: # no data, return None
return None
if data[0] == '\n' or bytes_from_end == length:
if data[0] == '\n' or bytes_from_end == length-1:
# found the last line, which should have the return value
if data[0] == '\n':
data = data[1:]

View File

@ -25,11 +25,17 @@ class DeviceManagerADB(DeviceManager):
packageName = 'org.mozilla.fennec_'
self.Init(packageName)
def __del__(self):
if self.host:
self.disconnectRemoteADB()
def Init(self, packageName):
# Initialization code that may fail: Catch exceptions here to allow
# successful initialization even if, for example, adb is not installed.
try:
self.verifyADB()
if self.host:
self.connectRemoteADB()
self.verifyRunAs(packageName)
except:
self.useRunAs = False
@ -78,7 +84,7 @@ class DeviceManagerADB(DeviceManager):
# to get it
# FIXME: this function buffers all output of the command into memory,
# always. :(
cmdline = subprocess.list2cmdline(cmd) + "; echo $?"
cmdline = " ".join(cmd) + "; echo $?"
# prepend cwd and env to command if necessary
if cwd:
@ -104,6 +110,12 @@ class DeviceManagerADB(DeviceManager):
return None
def connectRemoteADB(self):
self.checkCmd(["connect", self.host + ":" + str(self.port)])
def disconnectRemoteADB(self):
self.checkCmd(["disconnect", self.host + ":" + str(self.port)])
# external function
# returns:
# success: True

View File

@ -39,6 +39,7 @@
from devicemanagerADB import DeviceManagerADB
from devicemanagerSUT import DeviceManagerSUT
import StringIO
class DroidMixin(object):
"""Mixin to extend DeviceManager with Android-specific functionality"""
@ -59,7 +60,7 @@ class DroidMixin(object):
acmd = [ "am", "start", "-a", intent, "-W", "-n", "%s/.%s" % (app, activity)]
if extra_args:
acmd.extend(["--es", "args", " ".join(args)])
acmd.extend(["--es", "args", " ".join(extra_args)])
if env:
envCnt = 0
@ -69,7 +70,7 @@ class DroidMixin(object):
envCnt += 1
if url:
acmd.extend(["-d", ''.join(['"', url, '"'])])
acmd.extend(["-d", ''.join(["'", url, "'"])])
# shell output not that interesting and debugging logs should already
# show what's going on here... so just create an empty memory buffer

View File

@ -141,7 +141,7 @@ class RemoteAutomation(Automation):
nettools = NetworkTools()
return nettools.getLanIp()
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
def Process(self, cmd, stdout = None, stderr = None, env = None, cwd = None):
if stdout == None or stdout == -1 or stdout == subprocess.PIPE:
stdout = self._remoteLog
@ -151,7 +151,7 @@ class RemoteAutomation(Automation):
class RProcess(object):
# device manager process
dm = None
def __init__(self, dm, cmd, stdout = None, stderr = None, env = None, cwd = '.'):
def __init__(self, dm, cmd, stdout = None, stderr = None, env = None, cwd = None):
self.dm = dm
self.stdoutlen = 0
self.proc = dm.launchProcess(cmd, stdout, cwd, env, True)

View File

@ -67,6 +67,7 @@ import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.zip.Adler32;
import java.util.zip.CheckedInputStream;
@ -136,7 +137,7 @@ public class DoCommand {
String ffxProvider = "org.mozilla.ffxcp";
String fenProvider = "org.mozilla.fencp";
private final String prgVersion = "SUTAgentAndroid Version 1.06";
private final String prgVersion = "SUTAgentAndroid Version 1.07";
public enum Command
{
@ -2449,6 +2450,48 @@ private void CancelNotification()
}
}
}
else
{
// To kill processes other than Java applications - processes
// like xpcshell - a different strategy is necessary: use ps
// to find the process' PID.
try
{
pProc = Runtime.getRuntime().exec("ps");
RedirOutputThread outThrd = new RedirOutputThread(pProc, null);
outThrd.start();
outThrd.join(10000);
sTmp = outThrd.strOutput;
StringTokenizer stokLines = new StringTokenizer(sTmp, "\n");
while(stokLines.hasMoreTokens())
{
String sLine = stokLines.nextToken();
StringTokenizer stokColumns = new StringTokenizer(sLine, " \t\n");
stokColumns.nextToken();
String sPid = stokColumns.nextToken();
stokColumns.nextToken();
stokColumns.nextToken();
stokColumns.nextToken();
stokColumns.nextToken();
stokColumns.nextToken();
stokColumns.nextToken();
String sName = null;
if (stokColumns.hasMoreTokens())
{
sName = stokColumns.nextToken();
if (sName.contains(sProcName))
{
NewKillProc(sPid, out);
sRet = "Successfully killed " + sPid + " " + sName + "\n";
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
return (sRet);
}
@ -2872,15 +2915,10 @@ private void CancelNotification()
public String NewKillProc(String sProcId, OutputStream out)
{
String sRet = "";
String [] theArgs = new String [3];
theArgs[0] = "su";
theArgs[1] = "-c";
theArgs[2] = "kill " + sProcId;
try
{
pProc = Runtime.getRuntime().exec(theArgs);
pProc = Runtime.getRuntime().exec("kill "+sProcId);
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start();
outThrd.join(5000);

View File

@ -250,6 +250,8 @@ if not os.path.exists(source_dir):
patch('plugin_finish_decl.diff', 0, gcc_source_dir)
patch('pr49911.diff', 1, gcc_source_dir)
patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
patch('gcc-fixinc.patch', 1, gcc_source_dir)
patch('gcc-include.patch', 1, gcc_source_dir)
if os.path.exists(build_dir):
shutil.rmtree(build_dir)

View File

@ -0,0 +1,12 @@
diff -ru a/fixincludes/Makefile.in b/fixincludes/Makefile.in
--- a/fixincludes/Makefile.in 2009-07-30 18:33:49.000000000 -0400
+++ b/fixincludes/Makefile.in 2012-02-27 14:59:09.371875951 -0500
@@ -126,7 +126,7 @@
fixlib.o : fixlib.c
fixinc.sh : fixinc.in mkfixinc.sh Makefile
- srcdir="$(srcdir)" $(SHELL) $(srcdir)/mkfixinc.sh $(target)
+ echo "#!/bin/sh" > $@
$(srcdir)/fixincl.x: @MAINT@ fixincl.tpl inclhack.def
cd $(srcdir) ; $(SHELL) ./genfixes

View File

@ -0,0 +1,24 @@
diff -ru a/configure b/configure
--- a/configure 2010-10-06 06:29:55.000000000 -0400
+++ b/configure 2012-02-27 20:46:26.303460301 -0500
@@ -8047,7 +8047,7 @@
# being built; programs in there won't even run.
if test "${build}" = "${host}" && test -d ${srcdir}/gcc; then
# Search for pre-installed headers if nothing else fits.
- FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(build_tooldir)/bin/ -B$(build_tooldir)/lib/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include'
+ FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(exec_prefix)/bin/ -B$(exec_prefix)/lib/ -isystem $(exec_prefix)/include -isystem $(exec_prefix)/sys-include'
fi
if test "x${use_gnu_ld}" = x &&
diff -ru a/configure.ac b/configure.ac
--- a/configure.ac 2010-10-06 06:29:55.000000000 -0400
+++ b/configure.ac 2012-02-27 20:46:22.587442745 -0500
@@ -3100,7 +3100,7 @@
# being built; programs in there won't even run.
if test "${build}" = "${host}" && test -d ${srcdir}/gcc; then
# Search for pre-installed headers if nothing else fits.
- FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(build_tooldir)/bin/ -B$(build_tooldir)/lib/ -isystem $(build_tooldir)/include -isystem $(build_tooldir)/sys-include'
+ FLAGS_FOR_TARGET=$FLAGS_FOR_TARGET' -B$(exec_prefix)/bin/ -B$(exec_prefix)/lib/ -isystem $(exec_prefix)/include -isystem $(exec_prefix)/sys-include'
fi
if test "x${use_gnu_ld}" = x &&

View File

@ -73,7 +73,7 @@ nsSecurityNameSet::~nsSecurityNameSet()
NS_IMPL_ISUPPORTS1(nsSecurityNameSet, nsIScriptExternalNameSet)
static JSString *
getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv)
getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, unsigned argc, jsval *argv)
{
if (argc <= argNum || !JSVAL_IS_STRING(argv[argNum])) {
JS_ReportError(cx, "String argument expected");
@ -88,7 +88,7 @@ getStringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsv
}
static bool
getBytesArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsval *argv,
getBytesArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, unsigned argc, jsval *argv,
JSAutoByteString *bytes)
{
JSString *str = getStringArgument(cx, obj, argNum, argc, argv);
@ -97,7 +97,7 @@ getBytesArgument(JSContext *cx, JSObject *obj, PRUint16 argNum, uintN argc, jsva
static void
getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
uintN argc, jsval *argv, nsCString& aRetval)
unsigned argc, jsval *argv, nsCString& aRetval)
{
aRetval.Truncate();
@ -122,7 +122,7 @@ getUTF8StringArgument(JSContext *cx, JSObject *obj, PRUint16 argNum,
}
static JSBool
netscape_security_isPrivilegeEnabled(JSContext *cx, uintN argc, jsval *vp)
netscape_security_isPrivilegeEnabled(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@ -153,7 +153,7 @@ netscape_security_isPrivilegeEnabled(JSContext *cx, uintN argc, jsval *vp)
static JSBool
netscape_security_enablePrivilege(JSContext *cx, uintN argc, jsval *vp)
netscape_security_enablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@ -196,7 +196,7 @@ netscape_security_enablePrivilege(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
netscape_security_disablePrivilege(JSContext *cx, uintN argc, jsval *vp)
netscape_security_disablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@ -222,7 +222,7 @@ netscape_security_disablePrivilege(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
netscape_security_revertPrivilege(JSContext *cx, uintN argc, jsval *vp)
netscape_security_revertPrivilege(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@ -248,7 +248,7 @@ netscape_security_revertPrivilege(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
netscape_security_setCanEnablePrivilege(JSContext *cx, uintN argc, jsval *vp)
netscape_security_setCanEnablePrivilege(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@ -280,7 +280,7 @@ netscape_security_setCanEnablePrivilege(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
netscape_security_invalidate(JSContext *cx, uintN argc, jsval *vp)
netscape_security_invalidate(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)

View File

@ -42,6 +42,7 @@ interface nsIObjectFrame;
interface nsIPluginTag;
interface nsIDOMElement;
interface nsIDOMClientRect;
interface nsIURI;
%{C++
#include "nsNPAPIPluginInstance.h"
@ -51,7 +52,7 @@ interface nsIDOMClientRect;
/**
* This interface represents a content node that loads objects.
*/
[scriptable, uuid(6D8914C7-0E22-4452-8962-11B69BBE84D7)]
[scriptable, uuid(3FF07AB3-5BAC-4D98-9549-5BD15CCEBCD3)]
interface nsIObjectLoadingContent : nsISupports
{
const unsigned long TYPE_LOADING = 0;
@ -79,6 +80,14 @@ interface nsIObjectLoadingContent : nsISupports
*/
unsigned long getContentTypeForMIMEType(in AUTF8String aMimeType);
/**
* Gets the base URI to be used for this object. This differs from
* nsIContent::GetBaseURI in that it takes codebase attributes into
* account. The MIME type is required as some plugins (java) calculate
* this differently.
*/
nsIURI GetObjectBaseURI(in ACString aMimeType);
/**
* Returns the plugin instance if it has already been instantiated. This
* will never instantiate the plugin and so is safe to call even when

View File

@ -408,9 +408,10 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
nsISelectionController* selcon = textControl->GetSelectionController();
if (selcon) {
selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
if (!selection)
return NS_OK;
}
if (!selection)
return NS_OK;
}
else {
mWindow->GetSelection(getter_AddRefs(selection));
@ -449,11 +450,14 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
return NS_OK;
if (isChromeShell && textControl) {
// Only use the selection if it isn't collapsed.
bool isCollapsed = false;
selection->GetIsCollapsed(&isCollapsed);
if (!isCollapsed)
selection.swap(*aSelection);
// Only use the selection if the target node is in the selection.
bool selectionContainsTarget = false;
nsCOMPtr<nsIDOMNode> targetNode = do_QueryInterface(mSelectionTargetNode);
selection->ContainsNode(targetNode, false, &selectionContainsTarget);
if (!selectionContainsTarget)
return NS_OK;
selection.swap(*aSelection);
}
else {
// In content shells, a number of checks are made below to determine

View File

@ -176,7 +176,7 @@ nsWrapperCache::RemoveExpandoObject()
if (expando) {
JSCompartment *compartment = js::GetObjectCompartment(expando);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate *>(js_GetCompartmentPrivate(compartment));
static_cast<xpc::CompartmentPrivate *>(JS_GetCompartmentPrivate(compartment));
priv->RemoveDOMExpandoObject(expando);
}
}

View File

@ -598,7 +598,7 @@ nsObjectLoadingContent::InstantiatePluginInstance(const char* aMimeType, nsIURI*
if (!aURI) {
// We need some URI. If we have nothing else, use the base URI.
// XXX(biesi): The code used to do this. Not sure why this is correct...
GetObjectBaseURI(thisContent, getter_AddRefs(baseURI));
GetObjectBaseURI(nsCString(aMimeType), getter_AddRefs(baseURI));
aURI = baseURI;
}
@ -1163,7 +1163,7 @@ nsObjectLoadingContent::LoadObject(const nsAString& aURI,
nsIDocument* doc = thisContent->OwnerDoc();
nsCOMPtr<nsIURI> baseURI;
GetObjectBaseURI(thisContent, getter_AddRefs(baseURI));
GetObjectBaseURI(aTypeHint, getter_AddRefs(baseURI));
nsCOMPtr<nsIURI> uri;
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
@ -1194,6 +1194,51 @@ nsObjectLoadingContent::UpdateFallbackState(nsIContent* aContent,
}
}
bool
nsObjectLoadingContent::IsFileCodebaseAllowable(nsIURI* aBaseURI, nsIURI* aOriginURI)
{
nsCOMPtr<nsIFileURL> baseFileURL(do_QueryInterface(aBaseURI));
nsCOMPtr<nsIFileURL> originFileURL(do_QueryInterface(aOriginURI));
// get IFile handles and normalize
nsCOMPtr<nsIFile> originFile;
nsCOMPtr<nsIFile> baseFile;
if (!originFileURL || !baseFileURL ||
NS_FAILED(originFileURL->GetFile(getter_AddRefs(originFile))) ||
NS_FAILED(baseFileURL->GetFile(getter_AddRefs(baseFile))) ||
NS_FAILED(baseFile->Normalize()) ||
NS_FAILED(originFile->Normalize())) {
return false;
}
// If the origin is a directory, it should contain/equal baseURI
// Otherwise, its parent directory should contain/equal baseURI
bool origin_is_dir;
bool contained = false;
nsresult rv = originFile->IsDirectory(&origin_is_dir);
NS_ENSURE_SUCCESS(rv, false);
if (origin_is_dir) {
// originURI is a directory, ensure it contains the baseURI
rv = originFile->Contains(baseFile, true, &contained);
if (NS_SUCCEEDED(rv) && !contained) {
rv = originFile->Equals(baseFile, &contained);
}
} else {
// originURI is a file, ensure its parent contains the baseURI
nsCOMPtr<nsIFile> originParent;
rv = originFile->GetParent(getter_AddRefs(originParent));
if (NS_SUCCEEDED(rv) && originParent) {
rv = originParent->Contains(baseFile, true, &contained);
if (NS_SUCCEEDED(rv) && !contained) {
rv = originParent->Equals(baseFile, &contained);
}
}
}
return NS_SUCCEEDED(rv) && contained;
}
nsresult
nsObjectLoadingContent::LoadObject(nsIURI* aURI,
bool aNotify,
@ -1291,6 +1336,28 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
HandleBeingBlockedByContentPolicy(rv, shouldLoad);
return NS_OK;
}
// If this is a file:// URI, require that the codebase (baseURI)
// is contained within the same folder as the document origin (originURI)
// or within the document origin, if it is a folder.
// No originURI implies chrome, which bypasses the check
// -- bug 406541
nsCOMPtr<nsIURI> originURI;
nsCOMPtr<nsIURI> baseURI;
GetObjectBaseURI(aTypeHint, getter_AddRefs(baseURI));
rv = thisContent->NodePrincipal()->GetURI(getter_AddRefs(originURI));
if (NS_FAILED(rv)) {
Fallback(aNotify);
return NS_OK;
}
if (originURI) {
bool isfile;
if (NS_FAILED(originURI->SchemeIs("file", &isfile)) ||
(isfile && !IsFileCodebaseAllowable(baseURI, originURI))) {
Fallback(aNotify);
return NS_OK;
}
}
}
nsresult rv = NS_ERROR_UNEXPECTED;
@ -1408,7 +1475,7 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
// XXX(biesi). The plugin instantiation code used to pass the base URI
// here instead of the plugin URI for instantiation via class ID, so I
// continue to do so. Why that is, no idea...
GetObjectBaseURI(thisContent, getter_AddRefs(mURI));
GetObjectBaseURI(mContentType, getter_AddRefs(mURI));
if (!mURI) {
mURI = aURI;
}
@ -1785,25 +1852,29 @@ nsObjectLoadingContent::TypeForClassID(const nsAString& aClassID,
return NS_ERROR_NOT_AVAILABLE;
}
void
nsObjectLoadingContent::GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI)
NS_IMETHODIMP
nsObjectLoadingContent::GetObjectBaseURI(const nsACString & aMimeType, nsIURI** aURI)
{
// We want to use swap(); since this is just called from this file,
// we can assert this (callers use comptrs)
NS_PRECONDITION(*aURI == nsnull, "URI must be inited to zero");
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
// For plugins, the codebase attribute is the base URI
nsCOMPtr<nsIURI> baseURI = thisContent->GetBaseURI();
nsAutoString codebase;
thisContent->GetAttr(kNameSpaceID_None, nsGkAtoms::codebase,
codebase);
if (!codebase.IsEmpty()) {
nsContentUtils::NewURIWithDocumentCharset(aURI, codebase,
thisContent->OwnerDoc(),
baseURI);
} else {
baseURI.swap(*aURI);
if (codebase.IsEmpty() && aMimeType.Equals("application/x-java-vm")) {
// bug 406541
// Java resolves codebase="" as "/" -- so we replicate that quirk, to ensure
// we run security checks against the same path.
codebase.AssignLiteral("/");
}
nsContentUtils::NewURIWithDocumentCharset(aURI, codebase,
thisContent->OwnerDoc(),
baseURI);
return NS_OK;
}
nsObjectFrame*

View File

@ -253,6 +253,12 @@ class nsObjectLoadingContent : public nsImageLoadingContent
*/
static bool IsSuccessfulRequest(nsIRequest* aRequest);
/**
* Check if the given baseURI is contained in the same directory as the
* aOriginURI (or a child thereof)
*/
static bool IsFileCodebaseAllowable(nsIURI* aBaseURI, nsIURI* aOriginURI);
/**
* Check whether the URI can be handled internally.
*/
@ -299,14 +305,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
*/
nsresult TypeForClassID(const nsAString& aClassID, nsACString& aType);
/**
* Gets the base URI to be used for this object. This differs from
* nsIContent::GetBaseURI in that it takes codebase attributes into
* account.
*/
void GetObjectBaseURI(nsIContent* thisContent, nsIURI** aURI);
/**
* Gets the frame that's associated with this content node.
* Does not flush.

View File

@ -246,7 +246,7 @@ GetImageDataDimensions(JSContext *cx, JSObject *dataObject, uint32_t *width, uin
}
static JSBool
nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
@ -292,7 +292,7 @@ nsIDOMCanvasRenderingContext2D_CreateImageData(JSContext *cx, uintN argc, jsval
}
static JSBool
nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
@ -349,7 +349,7 @@ nsIDOMCanvasRenderingContext2D_GetImageData(JSContext *cx, uintN argc, jsval *vp
}
static JSBool
nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);

View File

@ -83,7 +83,7 @@ helper_isFloat32Array(JSObject *obj) {
* BufferData_array (int, js::TypedArray *, int)
*/
static JSBool
nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -156,7 +156,7 @@ nsIDOMWebGLRenderingContext_BufferData(JSContext *cx, uintN argc, jsval *vp)
* BufferSubData_array (int, int, js::TypedArray *)
*/
static JSBool
nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -228,7 +228,7 @@ nsIDOMWebGLRenderingContext_BufferSubData(JSContext *cx, uintN argc, jsval *vp)
* CompressedTexImage2D(uint, int, uint, int, int, int, ArrayBufferView)
*/
static JSBool
nsIDOMWebGLRenderingContext_CompressedTexImage2D(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_CompressedTexImage2D(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -278,7 +278,7 @@ nsIDOMWebGLRenderingContext_CompressedTexImage2D(JSContext *cx, uintN argc, jsva
* CompressedTexSubImage2D(uint, int, int, int, int, int, uint, ArrayBufferView)
*/
static JSBool
nsIDOMWebGLRenderingContext_CompressedTexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_CompressedTexSubImage2D(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -329,7 +329,7 @@ nsIDOMWebGLRenderingContext_CompressedTexSubImage2D(JSContext *cx, uintN argc, j
* ReadPixels(int, int, int, int, uint, uint, ArrayBufferView)
*/
static JSBool
nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -389,7 +389,7 @@ nsIDOMWebGLRenderingContext_ReadPixels(JSContext *cx, uintN argc, jsval *vp)
* TexImage2D(uint, int, uint, uint, uint, ImageData)
*/
static JSBool
nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -510,7 +510,7 @@ nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
* TexSubImage2D(uint, int, int, int, uint, uint, ImageData)
*/
static JSBool
nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, unsigned argc, jsval *vp)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -621,7 +621,7 @@ nsIDOMWebGLRenderingContext_TexSubImage2D(JSContext *cx, uintN argc, jsval *vp)
/* NOTE: There is a TN version of this below, update it as well */
static inline JSBool
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, uintN argc, jsval *vp, int nElements)
helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -695,7 +695,7 @@ helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(JSContext *cx, uintN argc, jsval
/* NOTE: There is a TN version of this below, update it as well */
static inline JSBool
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -769,7 +769,7 @@ helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(JSContext *cx, uintN argc, jsval
/* NOTE: There is a TN version of this below, update it as well */
static inline JSBool
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -842,7 +842,7 @@ helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(JSContext *cx, uintN argc,
}
static inline JSBool
helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, uintN argc, jsval *vp, int nElements)
helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, unsigned argc, jsval *vp, int nElements)
{
XPC_QS_ASSERT_CONTEXT_OK(cx);
JSObject *obj = JS_THIS_OBJECT(cx, vp);
@ -910,91 +910,91 @@ helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(JSContext *cx, uintN argc,
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform1iv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform1iv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 1);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform2iv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform2iv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 2);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform3iv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform3iv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 3);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform4iv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform4iv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_iv(cx, argc, vp, 4);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform1fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform1fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 1);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform2fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform2fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 2);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform3fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform3fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 3);
}
static JSBool
nsIDOMWebGLRenderingContext_Uniform4fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_Uniform4fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_Uniform_x_fv(cx, argc, vp, 4);
}
static JSBool
nsIDOMWebGLRenderingContext_UniformMatrix2fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_UniformMatrix2fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 2);
}
static JSBool
nsIDOMWebGLRenderingContext_UniformMatrix3fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_UniformMatrix3fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 3);
}
static JSBool
nsIDOMWebGLRenderingContext_UniformMatrix4fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_UniformMatrix4fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_UniformMatrix_x_fv(cx, argc, vp, 4);
}
static JSBool
nsIDOMWebGLRenderingContext_VertexAttrib1fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_VertexAttrib1fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 1);
}
static JSBool
nsIDOMWebGLRenderingContext_VertexAttrib2fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_VertexAttrib2fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 2);
}
static JSBool
nsIDOMWebGLRenderingContext_VertexAttrib3fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_VertexAttrib3fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 3);
}
static JSBool
nsIDOMWebGLRenderingContext_VertexAttrib4fv(JSContext *cx, uintN argc, jsval *vp)
nsIDOMWebGLRenderingContext_VertexAttrib4fv(JSContext *cx, unsigned argc, jsval *vp)
{
return helper_nsIDOMWebGLRenderingContext_VertexAttrib_x_fv(cx, argc, vp, 4);
}

View File

@ -64,6 +64,34 @@ function start() {
.getService(Components.interfaces.nsIPropertyBag2)
.getProperty("version");
kIsWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
// Workaround for Windows 2000 (driver?) which may crash itself.
if (parseFloat(version) <= 5.0) {
todo(false, "Test disabled on Windows 2000 and older. (To prevent possible system crash.)");
SimpleTest.finish();
return;
}
}
// we currently disable this test on version of Mac OSX older than 10.6,
// due to various weird failures, including one making getRenderbufferParameter tests
// on DEPTH_STENCIL fail
var kDarwinVersion = 0;
if (kIsMac) {
// code borrowed from browser/modules/test/browser_taskbar_preview.js
var is106orHigher = false;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
kDarwinVersion = parseFloat(Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2)
.getProperty("version"));
// the next line is correct: Mac OS 10.6 corresponds to Darwin version 10 !
// Mac OS 10.5 would be Darwin version 9. the |version| string we've got here
// is the Darwin version.
is106orHigher = (kDarwinVersion >= 10.0);
if (!is106orHigher) {
dump("WebGL mochitest disabled on Mac OSX versions older than 10.6\n");
SimpleTest.finish();
return;
}
}
// we currently disable this test on version of Mac OSX older than 10.6,
@ -404,6 +432,7 @@ function start() {
todo(false, errmsg + " (This is expected on SeaMonkey (tinderboxes).)");
else
ok(false, errmsg);
dump("WebGL mochitest failed: " + errmsg + "\n");
reporter.finishedTestSuite();
}
};

View File

@ -2160,7 +2160,7 @@ nsMediaCacheStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
PRUint32 streamBlock = PRUint32(mStreamOffset/BLOCK_SIZE);
PRUint32 offsetInStreamBlock =
PRUint32(mStreamOffset - streamBlock*BLOCK_SIZE);
PRInt32 size = NS_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
PRInt64 size = NS_MIN(aCount - count, BLOCK_SIZE - offsetInStreamBlock);
if (mStreamLength >= 0) {
// Don't try to read beyond the end of the stream
@ -2169,7 +2169,9 @@ nsMediaCacheStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
// Get out of here and return NS_OK
break;
}
size = NS_MIN(size, PRInt32(bytesRemaining));
size = NS_MIN(size, bytesRemaining);
// Clamp size until 64-bit file size issues (bug 500784) are fixed.
size = NS_MIN(size, PRInt64(PR_INT32_MAX));
}
PRInt32 bytes;
@ -2224,7 +2226,8 @@ nsMediaCacheStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
gMediaCache->NoteBlockUsage(this, cacheBlock, mCurrentMode, TimeStamp::Now());
PRInt64 offset = cacheBlock*BLOCK_SIZE + offsetInStreamBlock;
nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, size, &bytes);
NS_ASSERTION(size >= 0 && size <= PR_INT32_MAX, "Size out of range.");
nsresult rv = gMediaCache->ReadCacheFile(offset, aBuffer + count, PRInt32(size), &bytes);
if (NS_FAILED(rv)) {
if (count == 0)
return rv;

View File

@ -116,7 +116,7 @@ XBLFinalize(JSContext *cx, JSObject *obj)
}
static JSBool
XBLResolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
XBLResolve(JSContext *cx, JSObject *obj, jsid id, unsigned flags,
JSObject **objp)
{
// Note: if we get here, that means that the implementation for some binding

View File

@ -80,7 +80,7 @@ protected:
PRUnichar* mFieldText;
PRUint32 mFieldTextLength;
PRUint32 mLineNumber;
uintN mJSAttributes;
unsigned mJSAttributes;
};
#endif // nsXBLProtoImplField_h__

View File

@ -97,7 +97,7 @@ protected:
JSObject * mJSSetterObject;
};
uintN mJSAttributes; // A flag for all our JS properties (getter/setter/readonly/shared/enum)
unsigned mJSAttributes; // A flag for all our JS properties (getter/setter/readonly/shared/enum)
#ifdef DEBUG
bool mIsCompiled;

View File

@ -47,6 +47,7 @@ MODULE = dom
DIRS = \
interfaces/base \
interfaces/canvas \
interfaces/contacts \
interfaces/core \
interfaces/html \
interfaces/events \
@ -77,6 +78,7 @@ endif
DIRS += \
base \
battery \
contacts \
power \
sms \
src \

View File

@ -684,11 +684,6 @@ public:
NS_IMETHOD PreCreate(nsISupports *aNativeObj, JSContext *aCx,
JSObject *aGlobalObj, JSObject **aParentObj);
NS_IMETHOD AddProperty(nsIXPConnectWrappedNative *aWrapper, JSContext *aCx,
JSObject *aObj, jsid aId, jsval *aVp, bool *aRetval);
virtual void PreserveWrapper(nsISupports *aNative);
static nsIClassInfo *doCreate(nsDOMClassInfoData *aData)
{
return new IDBEventTargetSH(aData);
@ -5240,7 +5235,7 @@ GetDocument(JSObject *obj)
// static
JSBool
nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
jsid id, unsigned flags,
JSObject **objp)
{
if (flags & (JSRESOLVE_ASSIGNING | JSRESOLVE_DECLARING |
@ -5546,7 +5541,7 @@ FindConstructorFunc(const nsDOMClassInfoData *aDOMClassInfoData)
static nsresult
BaseStubConstructor(nsIWeakReference* aWeakOwner,
const nsGlobalNameStruct *name_struct, JSContext *cx,
JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSObject *obj, unsigned argc, jsval *argv, jsval *rval)
{
nsresult rv;
nsCOMPtr<nsISupports> native;
@ -6640,7 +6635,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
// Native code for window._content getter, this simply maps
// window._content to window.content for backwards compatibility only.
static JSBool
ContentWindowGetter(JSContext *cx, uintN argc, jsval *vp)
ContentWindowGetter(JSContext *cx, unsigned argc, jsval *vp)
{
JSObject *obj = JS_THIS_OBJECT(cx, vp);
if (!obj)
@ -7700,25 +7695,6 @@ IDBEventTargetSH::PreCreate(nsISupports *aNativeObj, JSContext *aCx,
return NS_OK;
}
NS_IMETHODIMP
IDBEventTargetSH::AddProperty(nsIXPConnectWrappedNative *aWrapper,
JSContext *aCx, JSObject *aObj, jsid aId,
jsval *aVp, bool *aRetval)
{
if (aId != sAddEventListener_id) {
IDBEventTargetSH::PreserveWrapper(GetNative(aWrapper, aObj));
}
return NS_OK;
}
void
IDBEventTargetSH::PreserveWrapper(nsISupports *aNative)
{
IDBWrapperCache *target = IDBWrapperCache::FromSupports(aNative);
nsContentUtils::PreserveWrapper(aNative, target);
}
// Element helper
static bool
@ -8901,7 +8877,7 @@ nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JSObject *obj,
JSBool
nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
uintN flags, JSObject **objp)
unsigned flags, JSObject **objp)
{
if (flags & JSRESOLVE_ASSIGNING) {
// Nothing to do here if we're assigning
@ -8971,7 +8947,7 @@ nsHTMLDocumentSH::ReleaseDocument(JSContext *cx, JSObject *obj)
}
JSBool
nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp)
nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp)
{
// Handle document.all("foo") style access to document.all.
@ -9097,7 +9073,7 @@ nsHTMLDocumentSH::DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj,
JSBool
nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
jsid id, unsigned flags,
JSObject **objp)
{
if (id == nsDOMClassInfo::sAll_id) {
@ -9120,7 +9096,7 @@ nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,
JSBool
nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
jsid id, unsigned flags,
JSObject **objp)
{
if (JSID_IS_STRING(id)) {

View File

@ -425,7 +425,7 @@ public:
JSObject * obj, JSObject * *_retval);
static JSBool GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
jsid id, unsigned flags,
JSObject **objp);
static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSObject *obj,
jsid id, jsval *vp);
@ -863,16 +863,16 @@ public:
static JSBool DocumentAllGetProperty(JSContext *cx, JSObject *obj, jsid id,
jsval *vp);
static JSBool DocumentAllNewResolve(JSContext *cx, JSObject *obj, jsid id,
uintN flags, JSObject **objp);
unsigned flags, JSObject **objp);
static void ReleaseDocument(JSContext *cx, JSObject *obj);
static JSBool CallToGetPropMapper(JSContext *cx, uintN argc, jsval *vp);
static JSBool CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp);
static JSBool DocumentAllHelperGetProperty(JSContext *cx, JSObject *obj,
jsid id, jsval *vp);
static JSBool DocumentAllHelperNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
jsid id, unsigned flags,
JSObject **objp);
static JSBool DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj,
jsid id, uintN flags,
jsid id, unsigned flags,
JSObject **objp);
NS_IMETHOD NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,

View File

@ -1227,48 +1227,8 @@ nsGlobalWindow::ClearControllers()
}
}
// static
void
nsGlobalWindow::TryClearWindowScope(nsISupports *aWindow)
{
nsGlobalWindow *window =
static_cast<nsGlobalWindow *>(static_cast<nsIDOMWindow*>(aWindow));
// This termination function might be called when any script evaluation in our
// context terminated, even if there are other scripts in the stack. Thus, we
// have to check again if a script is executing and post a new termination
// function if necessary.
window->ClearScopeWhenAllScriptsStop();
}
void
nsGlobalWindow::ClearScopeWhenAllScriptsStop()
{
NS_ASSERTION(IsInnerWindow(), "Must be an inner window");
// We cannot clear scope safely until all the scripts in our script context
// stopped. This might be a long wait, for example if one script is busy
// because it started a nested event loop for a modal dialog.
nsIScriptContext *jsscx = GetContextInternal();
if (jsscx && jsscx->GetExecutingScript()) {
// We ignore the return value because the only reason that we clear scope
// here is to try to prevent leaks. Failing to clear scope might mean that
// we'll leak more but if we don't have enough memory to allocate a
// termination function we probably don't have to worry about this anyway.
jsscx->SetTerminationFunction(TryClearWindowScope,
static_cast<nsIDOMWindow *>(this));
return;
}
NotifyWindowIDDestroyed("inner-window-destroyed");
nsIScriptContext *scx = GetContextInternal();
if (scx) {
scx->ClearScope(mJSObject, true);
}
}
void
nsGlobalWindow::FreeInnerObjects(bool aClearScope)
nsGlobalWindow::FreeInnerObjects()
{
NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
@ -1330,9 +1290,7 @@ nsGlobalWindow::FreeInnerObjects(bool aClearScope)
mIndexedDB = nsnull;
if (aClearScope) {
ClearScopeWhenAllScriptsStop();
}
NotifyWindowIDDestroyed("inner-window-destroyed");
if (mDummyJavaPluginOwner) {
// Tear down the dummy java plugin.
@ -1666,7 +1624,6 @@ nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
// Great, we're the original document, check for one of the other
// conditions.
if (mDoc == aNewDocument) {
// aClearScopeHint is false.
return true;
}
@ -1840,10 +1797,8 @@ WindowStateHolder::~WindowStateHolder()
// free it up.
// Note that FreeInnerObjects may already have been called on the
// inner window if its outer has already had SetDocShell(null)
// called. In this case the contexts will all be null and the
// true for aClearScope won't do anything; this is OK since
// SetDocShell(null) already did it.
mInnerWindow->FreeInnerObjects(true);
// called.
mInnerWindow->FreeInnerObjects();
}
}
@ -2006,12 +1961,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?");
// Make sure to clear scope on the outer window *before* we
// initialize the new inner window. If we don't, things
// (Object.prototype etc) could leak from the old outer to the new
// inner scope.
mContext->ClearScope(mJSObject, false);
if (reUseInnerWindow) {
// We're reusing the current inner window.
NS_ASSERTION(!currentInner->IsFrozen(),
@ -2081,8 +2030,6 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
}
if (currentInner && currentInner->mJSObject) {
bool termFuncSet = false;
if (oldDoc == aDocument) {
// Move the navigator from the old inner window to the new one since
// this is a document.write. This is safe from a same-origin point of
@ -2092,45 +2039,12 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
if (newInnerWindow->mNavigator) {
newInnerWindow->mNavigator->SetWindow(newInnerWindow);
}
// Suspend the current context's request before Pop() resumes the old
// context's request.
JSAutoSuspendRequest asr(cx);
// Pop our context here so that we get the correct one for the
// termination function.
cxPusher.Pop();
JSContext *oldCx = nsContentUtils::GetCurrentJSContext();
nsIScriptContext *callerScx;
if (oldCx && (callerScx = GetScriptContextFromJSContext(oldCx))) {
// We're called from document.open() (and document.open() is
// called from JS), clear the scope etc in a termination
// function on the calling context to prevent clearing the
// calling scope.
NS_ASSERTION(!currentInner->IsFrozen(),
"How does this opened window get into session history");
JSAutoRequest ar(oldCx);
callerScx->SetTerminationFunction(ClearWindowScope,
static_cast<nsIDOMWindow *>
(currentInner));
termFuncSet = true;
}
// Re-push our context.
cxPusher.Push(cx);
}
// Don't clear scope on our current inner window if it's going to be
// Don't free objects on our current inner window if it's going to be
// held in the bfcache.
if (!currentInner->IsFrozen()) {
// Skip the ClearScope if we set a termination function to do
// it ourselves, later.
currentInner->FreeInnerObjects(!termFuncSet);
currentInner->FreeInnerObjects();
}
}
@ -2177,7 +2091,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
JSCompartment *compartment = js::GetObjectCompartment(mJSObject);
xpc::CompartmentPrivate *priv =
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(cx, compartment));
static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
if (priv && priv->waiverWrapperMap) {
NS_ASSERTION(!JS_IsExceptionPending(cx),
"We might overwrite a pending exception!");
@ -2433,7 +2347,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
inner = (nsGlobalWindow*)PR_NEXT_LINK(inner)) {
NS_ASSERTION(!inner->mOuterWindow || inner->mOuterWindow == this,
"bad outer window pointer");
inner->FreeInnerObjects(true);
inner->FreeInnerObjects();
}
// Make sure that this is called before we null out the document.
@ -2455,10 +2369,6 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
mFocusedNode = nsnull;
}
if (mContext) {
mContext->ClearScope(mJSObject, true);
}
ClearControllers();
mChromeEventHandler = nsnull; // force release now
@ -8985,17 +8895,6 @@ nsGlobalWindow::CloseWindow(nsISupports *aWindow)
// else if OOM, better not to close. That might cause a crash.
}
// static
void
nsGlobalWindow::ClearWindowScope(nsISupports *aWindow)
{
nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryInterface(aWindow));
nsIScriptContext *scx = sgo->GetContext();
if (scx) {
scx->ClearScope(sgo->GetGlobalJSObject(), true);
}
}
//*****************************************************************************
// nsGlobalWindow: Timeout Functions
//*****************************************************************************

View File

@ -236,7 +236,7 @@ private:
class nsOuterWindowProxy : public js::Wrapper
{
public:
nsOuterWindowProxy() : js::Wrapper((uintN)0) {}
nsOuterWindowProxy() : js::Wrapper((unsigned)0) {}
virtual bool isOuterWindow() {
return true;
@ -595,11 +595,9 @@ protected:
virtual ~nsGlobalWindow();
void CleanUp(bool aIgnoreModalDialog);
void ClearControllers();
static void TryClearWindowScope(nsISupports* aWindow);
void ClearScopeWhenAllScriptsStop();
nsresult FinalClose();
void FreeInnerObjects(bool aClearScope);
void FreeInnerObjects();
nsGlobalWindow *CallerInnerWindow();
nsresult InnerSetNewDocument(nsIDocument* aDocument);
@ -677,7 +675,6 @@ protected:
nsIDOMWindow **aReturn);
static void CloseWindow(nsISupports* aWindow);
static void ClearWindowScope(nsISupports* aWindow);
// Timeout Functions
// Language agnostic timeout function (all args passed).

View File

@ -75,8 +75,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIScriptContextPrincipal,
NS_ISCRIPTCONTEXTPRINCIPAL_IID)
#define NS_ISCRIPTCONTEXT_IID \
{ 0xf3840057, 0x4fe5, 0x4f92, \
{ 0xa3, 0xb8, 0x27, 0xd7, 0x44, 0x6f, 0x72, 0x4d } }
{ 0x6d69fbee, 0x0723, 0x48f5, \
{ 0x82, 0x48, 0xcd, 0xcf, 0x88, 0xac, 0x25, 0x74 } }
/* This MUST match JSVERSION_DEFAULT. This version stuff if we don't
know what language we have is a little silly... */
@ -427,20 +427,6 @@ public:
*/
virtual nsresult InitClasses(JSObject* aGlobalObj) = 0;
/**
* Clear the scope object - may be called either as we are being torn down,
* or before we are attached to a different document.
*
* aClearFromProtoChain is probably somewhat JavaScript specific. It
* indicates that the global scope polluter should be removed from the
* prototype chain and that the objects in the prototype chain should
* also have their scopes cleared. We don't do this all the time
* because the prototype chain is shared between inner and outer
* windows, and needs to stay with inner windows that we're keeping
* around.
*/
virtual void ClearScope(void* aGlobalObj, bool aClearFromProtoChain) = 0;
/**
* Tell the context we're about to be reinitialize it.
*/

View File

@ -2722,7 +2722,7 @@ CheckUniversalXPConnectForTraceMalloc(JSContext *cx)
}
static JSBool
TraceMallocDisable(JSContext *cx, uintN argc, jsval *vp)
TraceMallocDisable(JSContext *cx, unsigned argc, jsval *vp)
{
if (!CheckUniversalXPConnectForTraceMalloc(cx))
return JS_FALSE;
@ -2733,7 +2733,7 @@ TraceMallocDisable(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
TraceMallocEnable(JSContext *cx, uintN argc, jsval *vp)
TraceMallocEnable(JSContext *cx, unsigned argc, jsval *vp)
{
if (!CheckUniversalXPConnectForTraceMalloc(cx))
return JS_FALSE;
@ -2744,7 +2744,7 @@ TraceMallocEnable(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
TraceMallocOpenLogFile(JSContext *cx, uintN argc, jsval *vp)
TraceMallocOpenLogFile(JSContext *cx, unsigned argc, jsval *vp)
{
int fd;
JSString *str;
@ -2772,7 +2772,7 @@ TraceMallocOpenLogFile(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
TraceMallocChangeLogFD(JSContext *cx, uintN argc, jsval *vp)
TraceMallocChangeLogFD(JSContext *cx, unsigned argc, jsval *vp)
{
if (!CheckUniversalXPConnectForTraceMalloc(cx))
return JS_FALSE;
@ -2794,7 +2794,7 @@ TraceMallocChangeLogFD(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
TraceMallocCloseLogFD(JSContext *cx, uintN argc, jsval *vp)
TraceMallocCloseLogFD(JSContext *cx, unsigned argc, jsval *vp)
{
if (!CheckUniversalXPConnectForTraceMalloc(cx))
return JS_FALSE;
@ -2810,7 +2810,7 @@ TraceMallocCloseLogFD(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
TraceMallocLogTimestamp(JSContext *cx, uintN argc, jsval *vp)
TraceMallocLogTimestamp(JSContext *cx, unsigned argc, jsval *vp)
{
if (!CheckUniversalXPConnectForTraceMalloc(cx))
return JS_FALSE;
@ -2827,7 +2827,7 @@ TraceMallocLogTimestamp(JSContext *cx, uintN argc, jsval *vp)
}
static JSBool
TraceMallocDumpAllocations(JSContext *cx, uintN argc, jsval *vp)
TraceMallocDumpAllocations(JSContext *cx, unsigned argc, jsval *vp)
{
if (!CheckUniversalXPConnectForTraceMalloc(cx))
return JS_FALSE;
@ -2875,7 +2875,7 @@ void NS_JProfStopProfiling();
void NS_JProfClearCircular();
static JSBool
JProfStartProfilingJS(JSContext *cx, uintN argc, jsval *vp)
JProfStartProfilingJS(JSContext *cx, unsigned argc, jsval *vp)
{
NS_JProfStartProfiling();
return JS_TRUE;
@ -2917,7 +2917,7 @@ void NS_JProfStartProfiling()
}
static JSBool
JProfStopProfilingJS(JSContext *cx, uintN argc, jsval *vp)
JProfStopProfilingJS(JSContext *cx, unsigned argc, jsval *vp)
{
NS_JProfStopProfiling();
return JS_TRUE;
@ -2931,7 +2931,7 @@ NS_JProfStopProfiling()
}
static JSBool
JProfClearCircularJS(JSContext *cx, uintN argc, jsval *vp)
JProfClearCircularJS(JSContext *cx, unsigned argc, jsval *vp)
{
NS_JProfClearCircular();
return JS_TRUE;
@ -2945,7 +2945,7 @@ NS_JProfClearCircular()
}
static JSBool
JProfSaveCircularJS(JSContext *cx, uintN argc, jsval *vp)
JProfSaveCircularJS(JSContext *cx, unsigned argc, jsval *vp)
{
// Not ideal...
NS_JProfStopProfiling();
@ -2969,7 +2969,7 @@ static JSFunctionSpec JProfFunctions[] = {
// how to use DMD.
static JSBool
DMDCheckJS(JSContext *cx, uintN argc, jsval *vp)
DMDCheckJS(JSContext *cx, unsigned argc, jsval *vp)
{
mozilla::DMDCheckAndDump();
return JS_TRUE;
@ -3015,82 +3015,6 @@ nsJSContext::InitClasses(JSObject* aGlobalObj)
return rv;
}
void
nsJSContext::ClearScope(void *aGlobalObj, bool aClearFromProtoChain)
{
// Push our JSContext on our thread's context stack.
nsCOMPtr<nsIJSContextStack> stack =
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
if (stack && NS_FAILED(stack->Push(mContext))) {
stack = nsnull;
}
if (aGlobalObj) {
JSObject *obj = (JSObject *)aGlobalObj;
JSAutoRequest ar(mContext);
JSAutoEnterCompartment ac;
ac.enterAndIgnoreErrors(mContext, obj);
// Grab a reference to the window property, which is the outer
// window, so that we can re-define it once we've cleared
// scope. This is what keeps the outer window alive in cases where
// nothing else does.
jsval window;
if (!JS_GetProperty(mContext, obj, "window", &window)) {
window = JSVAL_VOID;
JS_ClearPendingException(mContext);
}
JS_ClearScope(mContext, obj);
NS_ABORT_IF_FALSE(!xpc::WrapperFactory::IsXrayWrapper(obj), "unexpected wrapper");
if (window != JSVAL_VOID) {
if (!JS_DefineProperty(mContext, obj, "window", window,
JS_PropertyStub, JS_StrictPropertyStub,
JSPROP_ENUMERATE | JSPROP_READONLY |
JSPROP_PERMANENT)) {
JS_ClearPendingException(mContext);
}
}
if (!js::GetObjectParent(obj)) {
JS_ClearRegExpStatics(mContext, obj);
}
// Always clear watchpoints, to deal with two cases:
// 1. The first document for this window is loading, and a miscreant has
// preset watchpoints on the window object in order to attack the new
// document's privileged information.
// 2. A document loaded and used watchpoints on its own window, leaving
// them set until the next document loads. We must clean up window
// watchpoints here.
// Watchpoints set on document and subordinate objects are all cleared
// when those sub-window objects are finalized, after JS_ClearScope and
// a GC run that finds them to be garbage.
::JS_ClearWatchPointsForObject(mContext, obj);
// Since the prototype chain is shared between inner and outer (and
// stays with the inner), we don't clear things from the prototype
// chain when we're clearing an outer window whose current inner we
// still want.
if (aClearFromProtoChain) {
nsWindowSH::InvalidateGlobalScopePolluter(mContext, obj);
// Clear up obj's prototype chain, but not Object.prototype.
for (JSObject *o = ::JS_GetPrototype(obj), *next;
o && (next = ::JS_GetPrototype(o)); o = next)
::JS_ClearScope(mContext, o);
}
}
if (stack) {
stack->Pop(nsnull);
}
}
void
nsJSContext::WillInitializeContext()
{

View File

@ -161,7 +161,6 @@ public:
virtual void SetGCOnDestruction(bool aGCOnDestruction);
virtual nsresult InitClasses(JSObject* aGlobalObj);
virtual void ClearScope(void* aGlobalObj, bool bClearPolluters);
virtual void WillInitializeContext();
virtual void DidInitializeContext();

View File

@ -0,0 +1,404 @@
/* 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/. */
"use strict"
/* static functions */
let DEBUG = 0;
if (DEBUG)
debug = function (s) { dump("-*- ContactManager: " + s + "\n"); }
else
debug = function (s) {}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const nsIClassInfo = Ci.nsIClassInfo;
const CONTACTPROPERTIES_CID = Components.ID("{53ed7c20-ceda-11e0-9572-0800200c9a66}");
const nsIDOMContactProperties = Ci.nsIDOMContactProperties;
// ContactProperties is not directly instantiated. It is used as interface.
ContactProperties.prototype = {
classID : CONTACTPROPERTIES_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTPROPERTIES_CID,
contractID:"@mozilla.org/contactProperties;1",
classDescription: "ContactProperties",
interfaces: [nsIDOMContactProperties],
flags: nsIClassInfo.DOM_OBJECT}),
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactProperties])
}
//ContactAddress
const CONTACTADDRESS_CONTRACTID = "@mozilla.org/contactAddress;1";
const CONTACTADDRESS_CID = Components.ID("{27a568b0-cee1-11e0-9572-0800200c9a66}");
const nsIDOMContactAddress = Components.interfaces.nsIDOMContactAddress;
function ContactAddress(aStreetAddress, aLocality, aRegion, aPostalCode, aCountryName) {
this.streetAddress = aStreetAddress || null;
this.locality = aLocality || null;
this.region = aRegion || null;
this.postalCode = aPostalCode || null;
this.countryName = aCountryName || null;
};
function ContactProperties(aProp) { debug("ContactProperties Constructor"); }
ContactAddress.prototype = {
classID : CONTACTADDRESS_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID,
contractID: CONTACTADDRESS_CONTRACTID,
classDescription: "ContactAddress",
interfaces: [nsIDOMContactAddress],
flags: nsIClassInfo.DOM_OBJECT}),
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactAddress])
}
//ContactFindOptions
const CONTACTFINDOPTIONS_CONTRACTID = "@mozilla.org/contactFindOptions;1";
const CONTACTFINDOPTIONS_CID = Components.ID("{e31daea0-0cb6-11e1-be50-0800200c9a66}");
const nsIDOMContactFindOptions = Components.interfaces.nsIDOMContactFindOptions;
function ContactFindOptions(aFilterValue, aFilterBy, aFilterOp, aFilterLimit) {
this.filterValue = aFilterValue || '';
this.filterBy = new Array();
for (let field in aFilterBy)
this.filterBy.push(field);
this.filterOp = aFilterOp || '';
this.filterLimit = aFilterLimit || 0;
};
ContactFindOptions.prototype = {
classID : CONTACTFINDOPTIONS_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACTFINDOPTIONS_CID,
contractID: CONTACTFINDOPTIONS_CONTRACTID,
classDescription: "ContactFindOptions",
interfaces: [nsIDOMContactFindOptions],
flags: nsIClassInfo.DOM_OBJECT}),
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactFindOptions])
}
//Contact
const CONTACT_CONTRACTID = "@mozilla.org/contact;1";
const CONTACT_CID = Components.ID("{da0f7040-388b-11e1-b86c-0800200c9a66}");
const nsIDOMContact = Components.interfaces.nsIDOMContact;
function Contact() { debug("Contact constr: "); };
Contact.prototype = {
init: function init(aProp) {
// Accept non-array strings for DOMString[] properties and convert them.
function _create(aField) {
if (typeof aField == "string")
return new Array(aField);
return aField;
};
this.name = _create(aProp.name) || null;
this.honorificPrefix = _create(aProp.honorificPrefix) || null;
this.givenName = _create(aProp.givenName) || null;
this.additionalName = _create(aProp.additionalName) || null;
this.familyName = _create(aProp.familyName) || null;
this.honorificSuffix = _create(aProp.honorificSuffix) || null;
this.nickname = _create(aProp.nickname) || null;
this.email = _create(aProp.email) || null;
this.photo = _create(aProp.photo) || null;
this.url = _create(aProp.url) || null;
this.category = _create(aProp.category) || null;
if (aProp.adr) {
// Make sure adr argument is an array. Instanceof doesn't work.
aProp.adr = aProp.adr.length == undefined ? [aProp.adr] : aProp.adr;
this.adr = new Array();
for (let i = 0; i < aProp.adr.length; i++)
this.adr.push(new ContactAddress(aProp.adr[i].streetAddress, aProp.adr[i].locality,
aProp.adr[i].region, aProp.adr[i].postalCode,
aProp.adr[i].countryName));
} else {
this.adr = null;
}
this.tel = _create(aProp.tel) || null;
this.org = _create(aProp.org) || null;
this.bday = (aProp.bday == "undefined" || aProp.bday == null) ? null : new Date(aProp.bday);
this.note = _create(aProp.note) || null;
this.impp = _create(aProp.impp) || null;
this.anniversary = (aProp.anniversary == "undefined" || aProp.anniversary == null) ? null : new Date(aProp.anniversary);
this.sex = (aProp.sex != "undefined") ? aProp.sex : null;
this.genderIdentity = (aProp.genderIdentity != "undefined") ? aProp.genderIdentity : null;
},
get published () {
return this._published;
},
set published(aPublished) {
this._published = aPublished;
},
get updated () {
return this._updated;
},
set updated(aUpdated) {
this._updated = aUpdated;
},
classID : CONTACT_CID,
classInfo : XPCOMUtils.generateCI({classID: CONTACT_CID,
contractID: CONTACT_CONTRACTID,
classDescription: "Contact",
interfaces: [nsIDOMContact, nsIDOMContactProperties],
flags: nsIClassInfo.DOM_OBJECT}),
QueryInterface : XPCOMUtils.generateQI([nsIDOMContact, nsIDOMContactProperties])
}
// ContactManager
const CONTACTMANAGER_CONTRACTID = "@mozilla.org/contactManager;1";
const CONTACTMANAGER_CID = Components.ID("{50a820b0-ced0-11e0-9572-0800200c9a66}");
const nsIDOMContactManager = Components.interfaces.nsIDOMContactManager;
function ContactManager()
{
debug("Constructor");
}
ContactManager.prototype = {
save: function save(aContact) {
let request;
if (this.hasPrivileges) {
debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
let newContact = {};
newContact.properties = {
name: [],
honorificPrefix: [],
givenName: [],
additionalName: [],
familyName: [],
honorificSuffix: [],
nickname: [],
email: [],
photo: [],
url: [],
category: [],
adr: [],
tel: [],
org: [],
bday: null,
note: [],
impp: [],
anniversary: null,
sex: null,
genderIdentity: null
};
for (let field in newContact.properties)
newContact.properties[field] = aContact[field];
if (aContact.id == "undefined") {
debug("Create id!");
aContact.id = this._getRandomId();
}
this._setMetaData(newContact, aContact);
debug("send: " + JSON.stringify(newContact));
request = this._rs.createRequest(this._window);
this._mm.sendAsyncMessage("Contact:Save", {contact: newContact,
requestID: this.getRequestId({ request: request })});
return request;
} else {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
},
remove: function removeContact(aRecord) {
let request;
if (this.hasPrivileges) {
request = this._rs.createRequest(this._window);
this._mm.sendAsyncMessage("Contact:Remove", {id: aRecord.id,
requestID: this.getRequestId({ request: request })});
return request;
} else {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
},
_setMetaData: function(aNewContact, aRecord) {
aNewContact.id = aRecord.id;
aNewContact.published = aRecord.published;
aNewContact.updated = aRecord.updated;
},
_convertContactsArray: function(aContacts) {
let contacts = new Array();
for (let i in aContacts) {
let newContact = new Contact();
newContact.init(aContacts[i].properties);
this._setMetaData(newContact, aContacts[i]);
contacts.push(newContact);
}
return contacts;
},
getRequestId: function(aRequest) {
let id = "id" + this._getRandomId();
this._requests[id] = aRequest;
return id;
},
getRequest: function(aId) {
if (this._requests[aId])
return this._requests[aId].request;
},
removeRequest: function(aId) {
if (this._requests[aId])
delete this._requests[aId];
},
_getRandomId: function() {
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
},
receiveMessage: function(aMessage) {
debug("Contactmanager::receiveMessage: " + aMessage.name);
let msg = aMessage.json;
let contacts = msg.contacts;
switch (aMessage.name) {
case "Contacts:Find:Return:OK":
let req = this.getRequest(msg.requestID);
if (req) {
let result = this._convertContactsArray(contacts);
debug("result: " + JSON.stringify(result));
this._rs.fireSuccess(req, result);
} else {
debug("no request stored!" + msg.requestID);
}
break;
case "Contact:Save:Return:OK":
case "Contacts:Clear:Return:OK":
case "Contact:Remove:Return:OK":
req = this.getRequest(msg.requestID);
if (req)
this._rs.fireSuccess(req, 0);
break;
case "Contacts:Find:Return:KO":
case "Contact:Save:Return:KO":
case "Contact:Remove:Return:KO":
case "Contacts:Clear:Return:KO":
req = this.getRequest(msg.requestID);
if (req)
this._rs.fireError(req, msg.errorMsg);
break;
default:
debug("Wrong message: " + aMessage.name);
}
this.removeRequest(msg.requestID);
},
find: function(aOptions) {
let request;
if (this.hasPrivileges) {
request = this._rs.createRequest(this._window);
this._mm.sendAsyncMessage("Contacts:Find", {findOptions: aOptions,
requestID: this.getRequestId({ request: request })});
return request;
} else {
debug("find not allowed");
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
},
clear: function() {
let request;
if (this.hasPrivileges) {
request = this._rs.createRequest(this._window);
this._mm.sendAsyncMessage("Contacts:Clear", {requestID: this.getRequestId({ request: request })});
return request;
} else {
debug("clear not allowed");
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
},
init: function(aWindow) {
// Set navigator.mozContacts to null.
if (!Services.prefs.getBoolPref("dom.mozContacts.enabled"))
return null;
this._window = aWindow;
this._messages = ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
"Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO",
"Contact:Save:Return:OK", "Contact:Save:Return:KO",
"Contact:Remove:Return:OK", "Contact:Remove:Return:KO"];
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
this._messages.forEach((function(msgName) {
this._mm.addMessageListener(msgName, this);
}).bind(this));
this._rs = Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
this._requests = [];
Services.obs.addObserver(this, "inner-window-destroyed", false);
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this._innerWindowID = util.currentInnerWindowID;
let principal = aWindow.document.nodePrincipal;
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
let perm = principal == secMan.getSystemPrincipal() ?
Ci.nsIPermissionManager.ALLOW_ACTION :
Services.perms.testExactPermission(principal.URI, "webcontacts-manage");
//only pages with perm set can use the contacts
this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
debug("has privileges :" + this.hasPrivileges);
},
observe: function(aSubject, aTopic, aData) {
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID) {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._messages.forEach((function(msgName) {
this._mm.removeMessageListener(msgName, this);
}).bind(this));
this._mm = null;
this._messages = null;
this._requests = null;
this._window = null;
this._innerWindowID = null;
}
},
classID : CONTACTMANAGER_CID,
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactManager, Ci.nsIDOMGlobalPropertyInitializer]),
classInfo : XPCOMUtils.generateCI({classID: CONTACTMANAGER_CID,
contractID: CONTACTMANAGER_CONTRACTID,
classDescription: "ContactManager",
interfaces: [nsIDOMContactManager],
flags: nsIClassInfo.DOM_OBJECT})
}
const NSGetFactory = XPCOMUtils.generateNSGetFactory([Contact, ContactManager, ContactProperties, ContactAddress, ContactFindOptions])

View File

@ -0,0 +1,16 @@
component {53ed7c20-ceda-11e0-9572-0800200c9a66} ContactManager.js
contract @mozilla.org/contactProperties;1 {53ed7c20-ceda-11e0-9572-0800200c9a66}
component {27a568b0-cee1-11e0-9572-0800200c9a66} ContactManager.js
contract @mozilla.org/contactAddress;1 {27a568b0-cee1-11e0-9572-0800200c9a66}
component {e31daea0-0cb6-11e1-be50-0800200c9a66} ContactManager.js
contract @mozilla.org/contactFindOptions;1 {e31daea0-0cb6-11e1-be50-0800200c9a66}
component {da0f7040-388b-11e1-b86c-0800200c9a66} ContactManager.js
contract @mozilla.org/contact;1 {da0f7040-388b-11e1-b86c-0800200c9a66}
category JavaScript-global-constructor mozContact @mozilla.org/contact;1
component {50a820b0-ced0-11e0-9572-0800200c9a66} ContactManager.js
contract @mozilla.org/contactManager;1 {50a820b0-ced0-11e0-9572-0800200c9a66}
category JavaScript-navigator-property mozContacts @mozilla.org/contactManager;1

47
dom/contacts/Makefile.in Normal file
View File

@ -0,0 +1,47 @@
# 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/.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = \
$(srcdir) \
$(NULL)
include $(DEPTH)/config/autoconf.mk
ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
VPATH += $(srcdir)/fallback
endif
MODULE = dom
LIBRARY_NAME = jsdomcontacts_s
LIBXUL_LIBRARY = 1
EXTRA_COMPONENTS = \
ContactManager.js \
ContactManager.manifest \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),gonk)
EXTRA_JS_MODULES = ContactService.jsm \
$(NULL)
EXTRA_JS_MODULES += ContactDB.jsm \
$(NULL)
endif
ifdef ENABLE_TESTS
DIRS += tests
endif
# Add VPATH to LOCAL_INCLUDES so we are going to include the correct backend
# subdirectory (and the ipc one).
LOCAL_INCLUDES += $(VPATH:%=-I%)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk
DEFINES += -D_IMPL_NS_LAYOUT

View File

@ -0,0 +1,410 @@
/* 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/. */
"use strict";
const EXPORTED_SYMBOLS = ['ContactDB'];
let DEBUG = 0;
/* static functions */
if (DEBUG)
debug = function (s) { dump("-*- ContactDB component: " + s + "\n"); }
else
debug = function (s) {}
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
const DB_NAME = "contacts";
const DB_VERSION = 1;
const STORE_NAME = "contacts";
function ContactDB(aGlobal) {
debug("Constructor");
this._indexedDB = aGlobal.mozIndexedDB;
}
ContactDB.prototype = {
// Cache the DB
db: null,
close: function close() {
debug("close");
if (this.db)
this.db.close();
},
/**
* Prepare the database. This may include opening the database and upgrading
* it to the latest schema version.
*
* @return (via callback) a database ready for use.
*/
ensureDB: function ensureDB(callback, failureCb) {
if (this.db) {
debug("ensureDB: already have a database, returning early.");
callback(this.db);
return;
}
let self = this;
debug("try to open database:" + DB_NAME + " " + DB_VERSION);
let request = this._indexedDB.open(DB_NAME, DB_VERSION);
request.onsuccess = function (event) {
debug("Opened database:", DB_NAME, DB_VERSION);
self.db = event.target.result;
self.db.onversionchange = function(event) {
debug("WARNING: DB modified from a different window.");
}
callback(self.db);
};
request.onupgradeneeded = function (event) {
debug("Database needs upgrade:" + DB_NAME + event.oldVersion + event.newVersion);
debug("Correct new database version:" + event.newVersion == DB_VERSION);
let db = event.target.result;
switch (event.oldVersion) {
case 0:
debug("New database");
self.createSchema(db);
break;
default:
debug("No idea what to do with old database version:" + event.oldVersion);
failureCb(event.target.errorMessage);
break;
}
};
request.onerror = function (event) {
debug("Failed to open database:", DB_NAME);
failureCb(event.target.errorMessage);
};
request.onblocked = function (event) {
debug("Opening database request is blocked.");
};
},
/**
* Create the initial database schema.
*
* The schema of records stored is as follows:
*
* {id: "...", // UUID
* published: Date(...), // First published date.
* updated: Date(...), // Last updated date.
* properties: {...} // Object holding the ContactProperties
* }
*/
createSchema: function createSchema(db) {
let objectStore = db.createObjectStore(STORE_NAME, {keyPath: "id"});
// Metadata indexes
objectStore.createIndex("published", "published", { unique: false });
objectStore.createIndex("updated", "updated", { unique: false });
// Properties indexes
objectStore.createIndex("nickname", "properties.nickname", { unique: false, multiEntry: true });
objectStore.createIndex("name", "properties.name", { unique: false, multiEntry: true });
objectStore.createIndex("familyName", "properties.familyName", { unique: false, multiEntry: true });
objectStore.createIndex("givenName", "properties.givenName", { unique: false, multiEntry: true });
objectStore.createIndex("tel", "properties.tel", { unique: false, multiEntry: true });
objectStore.createIndex("email", "properties.email", { unique: false, multiEntry: true });
objectStore.createIndex("note", "properties.note", { unique: false, multiEntry: true });
debug("Created object stores and indexes");
},
/**
* Start a new transaction.
*
* @param txn_type
* Type of transaction (e.g. IDBTransaction.READ_WRITE)
* @param callback
* Function to call when the transaction is available. It will
* be invoked with the transaction and the 'contacts' object store.
* @param successCb [optional]
* Success callback to call on a successful transaction commit.
* @param failureCb [optional]
* Error callback to call when an error is encountered.
*/
newTxn: function newTxn(txn_type, callback, successCb, failureCb) {
this.ensureDB(function (db) {
debug("Starting new transaction" + txn_type);
let txn = db.transaction(STORE_NAME, txn_type);
debug("Retrieving object store", STORE_NAME);
let store = txn.objectStore(STORE_NAME);
txn.oncomplete = function (event) {
debug("Transaction complete. Returning to callback.");
successCb(txn.result);
};
txn.onabort = function (event) {
debug("Caught error on transaction" + event.target.errorCode);
switch(event.target.errorCode) {
case Ci.nsIIDBDatabaseException.ABORT_ERR:
case Ci.nsIIDBDatabaseException.CONSTRAINT_ERR:
case Ci.nsIIDBDatabaseException.DATA_ERR:
case Ci.nsIIDBDatabaseException.TRANSIENT_ERR:
case Ci.nsIIDBDatabaseException.NOT_ALLOWED_ERR:
case Ci.nsIIDBDatabaseException.NOT_FOUND_ERR:
case Ci.nsIIDBDatabaseException.QUOTA_ERR:
case Ci.nsIIDBDatabaseException.READ_ONLY_ERR:
case Ci.nsIIDBDatabaseException.TIMEOUT_ERR:
case Ci.nsIIDBDatabaseException.TRANSACTION_INACTIVE_ERR:
case Ci.nsIIDBDatabaseException.VERSION_ERR:
case Ci.nsIIDBDatabaseException.UNKNOWN_ERR:
failureCb("UnknownError");
break;
default:
debug("Unknown errorCode", event.target.errorCode);
failureCb("UnknownError");
break;
}
};
callback(txn, store);
}, failureCb);
},
// Todo: add searchfields. "Tom" should be a result with T, t, To, to...
makeImport: function makeImport(aContact) {
let contact = {};
contact.properties = {
name: [],
honorificPrefix: [],
givenName: [],
additionalName: [],
familyName: [],
honorificSuffix: [],
nickname: [],
email: [],
photo: [],
url: [],
category: [],
adr: [],
tel: [],
org: [],
bday: null,
note: [],
impp: [],
anniversary: null,
sex: null,
genderIdentity: null
};
for (let field in aContact.properties) {
contact.properties[field] = aContact.properties[field];
}
contact.updated = aContact.updated;
contact.published = aContact.published;
contact.id = aContact.id;
return contact;
},
// Needed to remove searchfields
makeExport: function makeExport(aRecord) {
let contact = {};
contact.properties = aRecord.properties;
for (let field in aRecord.properties)
contact.properties[field] = aRecord.properties[field];
contact.updated = aRecord.updated;
contact.published = aRecord.published;
contact.id = aRecord.id;
return contact;
},
updateRecordMetadata: function updateRecordMetadata(record) {
if (!record.id) {
Cu.reportError("Contact without ID");
}
if (!record.published) {
record.published = new Date();
}
record.updated = new Date();
},
saveContact: function saveContact(aContact, successCb, errorCb) {
let contact = this.makeImport(aContact);
this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
debug("Going to update" + JSON.stringify(contact));
// Look up the existing record and compare the update timestamp.
// If no record exists, just add the new entry.
let newRequest = store.get(contact.id);
newRequest.onsuccess = function (event) {
if (!event.target.result) {
debug("new record!")
this.updateRecordMetadata(contact);
store.put(contact);
} else {
debug("old record!")
if (new Date(typeof contact.updated === "undefined" ? 0 : contact.updated) < new Date(event.target.result.updated)) {
debug("rev check fail!");
txn.abort();
return;
} else {
debug("rev check OK");
contact.published = event.target.result.published;
contact.updated = new Date();
store.put(contact);
}
}
}.bind(this);
}.bind(this), successCb, errorCb);
},
removeContact: function removeContact(aId, aSuccessCb, aErrorCb) {
this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
debug("Going to delete" + aId);
store.delete(aId);
}, aSuccessCb, aErrorCb);
},
clear: function clear(aSuccessCb, aErrorCb) {
this.newTxn(Ci.nsIIDBTransaction.READ_WRITE, function (txn, store) {
debug("Going to clear all!");
store.clear();
}, aSuccessCb, aErrorCb);
},
/**
* @param successCb
* Callback function to invoke with result array.
* @param failureCb [optional]
* Callback function to invoke when there was an error.
* @param options [optional]
* Object specifying search options. Possible attributes:
* - filterBy
* - filterOp
* - filterValue
* - count
* Possibly supported in the future:
* - fields
* - sortBy
* - sortOrder
* - startIndex
*/
find: function find(aSuccessCb, aFailureCb, aOptions) {
debug("ContactDB:find val:" + aOptions.filterValue + " by: " + aOptions.filterBy + " op: " + aOptions.filterOp + "\n");
let self = this;
this.newTxn(Ci.nsIIDBTransaction.READ_ONLY, function (txn, store) {
if (aOptions && aOptions.filterOp == "equals") {
self._findWithIndex(txn, store, aOptions);
} else if (aOptions && aOptions.filterBy) {
self._findWithSearch(txn, store, aOptions);
} else {
self._findAll(txn, store, aOptions);
}
}, aSuccessCb, aFailureCb);
},
_findWithIndex: function _findWithIndex(txn, store, options) {
debug("_findWithIndex: " + options.filterValue +" " + options.filterOp + " " + options.filterBy + " ");
let fields = options.filterBy;
for (let key in fields) {
debug("key: " + fields[key]);
if (!store.indexNames.contains(fields[key]) && !fields[key] == "id") {
debug("Key not valid!" + fields[key] + ", " + store.indexNames);
txn.abort();
return;
}
}
// lookup for all keys
if (options.filterBy.length == 0) {
debug("search in all fields!" + JSON.stringify(store.indexNames));
for(let myIndex = 0; myIndex < store.indexNames.length; myIndex++) {
fields = Array.concat(fields, store.indexNames[myIndex])
}
}
let filter_keys = fields.slice();
for (let key = filter_keys.shift(); key; key = filter_keys.shift()) {
let request;
if (key == "id") {
// store.get would return an object and not an array
request = store.getAll(options.filterValue);
} else {
debug("Getting index: " + key);
let index = store.index(key);
request = index.getAll(options.filterValue, options.filterLimit);
}
if (!txn.result)
txn.result = {};
request.onsuccess = function (event) {
debug("Request successful. Record count:" + event.target.result.length);
for (let i in event.target.result)
txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);
}.bind(this);
}
},
// Will be replaced by _findWithIndex once all searchfields are added.
_findWithSearch: function _findWithSearch(txn, store, options) {
debug("_findWithSearch:" + options.filterValue + options.filterOp)
store.getAll().onsuccess = function (event) {
debug("Request successful." + event.target.result);
txn.result = event.target.result.filter(function (record) {
let properties = record.properties;
for (let i = 0; i < options.filterBy.length; i++) {
let field = options.filterBy[i];
if (!properties[field])
continue;
let value = '';
switch (field) {
case "name":
case "familyName":
case "givenName":
case "nickname":
case "email":
case "tel":
case "note":
value = [f for each (f in [properties[field]])].join("\n") || '';
break;
default:
value = properties[field];
debug("unknown field: " + field);
}
let match = false;
switch (options.filterOp) {
case "icontains":
match = value.toLowerCase().indexOf(options.filterValue.toLowerCase()) != -1;
break;
case "contains":
match = value.indexOf(options.filterValue) != -1;
break;
case "equals":
match = value == options.filterValue;
break
}
if (match)
return true;
}
return false;
}).map(this.makeExport.bind(this));
}.bind(this);
},
_findAll: function _findAll(txn, store, options) {
debug("ContactDB:_findAll: " + JSON.stringify(options));
if (!txn.result)
txn.result = {};
store.getAll(null, options.filterLimit).onsuccess = function (event) {
debug("Request successful. Record count:", event.target.result.length);
for (let i in event.target.result)
txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]);
}.bind(this);
}
};

View File

@ -0,0 +1,96 @@
/* 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/. */
"use strict"
let DEBUG = 0;
if (DEBUG)
debug = function (s) { dump("-*- Fallback ContactService component: " + s + "\n"); }
else
debug = function (s) {}
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
let EXPORTED_SYMBOLS = ["DOMContactManager"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ContactDB.jsm");
let myGlobal = this;
let DOMContactManager = {
init: function() {
debug("Init");
this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"];
this._messages.forEach((function(msgName) {
this._mm.addMessageListener(msgName, this);
}).bind(this));
var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
idbManager.initWindowless(myGlobal);
this._db = new ContactDB(myGlobal);
Services.obs.addObserver(this, "profile-before-change", false);
try {
let hosts = Services.prefs.getCharPref("dom.mozContacts.whitelist")
hosts.split(",").forEach(function(aHost) {
debug("Add host: " + JSON.stringify(aHost));
if (aHost.length > 0)
Services.perms.add(Services.io.newURI(aHost, null, null), "webcontacts-manage",
Ci.nsIPermissionManager.ALLOW_ACTION);
});
} catch(e) { debug(e); }
},
observe: function(aSubject, aTopic, aData) {
myGlobal = null;
this._messages.forEach((function(msgName) {
this._mm.removeMessageListener(msgName, this);
}).bind(this));
Services.obs.removeObserver(this, "profile-before-change");
this._mm = null;
this._messages = null;
if (this._db)
this._db.close();
},
receiveMessage: function(aMessage) {
debug("Fallback DOMContactManager::receiveMessage " + aMessage.name);
let msg = aMessage.json;
switch (aMessage.name) {
case "Contacts:Find":
let result = new Array();
this._db.find(
function(contacts) {
for (let i in contacts)
result.push(contacts[i]);
debug("result:" + JSON.stringify(result));
this._mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
}.bind(this),
function(aErrorMsg) { this._mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
msg.findOptions);
break;
case "Contact:Save":
this._db.saveContact(msg.contact, function() {this._mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID }); }.bind(this),
function(aErrorMsg) { this._mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
break;
case "Contact:Remove":
this._db.removeContact(msg.id,
function() {this._mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID }); }.bind(this),
function(aErrorMsg) {this._mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
break;
case "Contacts:Clear":
this._db.clear(function() { this._mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
function(aErrorMsg) { this._mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
}
}
}
DOMContactManager.init();

View File

@ -0,0 +1,28 @@
# 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/.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = dom/contacts/tests
include $(DEPTH)/config/autoconf.mk
DIRS = \
$(NULL)
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_contacts_basics.html \
$(NULL)
_CHROME_TEST_FILES = \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)

View File

@ -0,0 +1,666 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id={674720}
-->
<head>
<title>Test for Bug {674720} WebContacts</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={674720}">Mozilla Bug {674720}</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
"use strict"
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager)
.add(SpecialPowers.getDocumentURIObject(window.document),
"webcontacts-manage",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
var adr1 = {
streetAddress: "street 1",
locality: "locality 1",
region: "region 1",
postalCode: "postal code 1",
countryName: "country 1"
};
var adr2 = {
streetAddress: "street2",
locality: "locality2",
region: "region2",
postalCode: "postal code2",
countryName: "country2"
};
var properties1 = {
name: "Testname1",
familyName: "TestFamilyName",
givenName: ["Test1","Test2"],
nickname: "nicktest",
tel: ["123456"],
adr: adr1
};
var properties2 = {
name: ["dummyName", "dummyName2"],
familyName: "dummyFamilyName",
givenName: "dummyGivenName",
honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
honorificSuffix: "dummyHonorificSuffix",
additionalName: "dummyadditionalName",
nickname: "dummyNickname",
tel: ["123456789", "234567890"],
email: ["a@b.c", "b@c.d"],
adr: [adr1, adr2],
impp: ["im1", "im2"],
org: ["org1", "org2"],
bday: new Date("1980, 12, 01"),
note: "test note",
photo: ["pic1", "pic2"],
category: ["cat1", "cat2"],
url: ["www.1.com", "www.2.com"],
anniversary: new Date("2000, 12, 01"),
sex: "male",
genderIdentity: "test"
};
var sample_id1;
var sample_id2;
var createResult1;
var createResult2;
var findResult1;
var findResult2;
function clearTemps() {
sample_id1 = null;
sample_id2 = null;
createResult1 = null;
createResult2 = null;
findResult1 = null;
findResult2 = null;
}
function onUnwantedSuccess() {
ok(false, "onUnwantedSuccess: shouldn't get here");
}
function onFailure() {
ok(false, "in on Failure!");
}
function checkStr(str1, str2, msg) {
if (str1)
ok(typeof str1 == "string" ? [str1] : str1, (typeof str2 == "string") ? [str2] : str2, msg);
}
function checkAddress(adr1, adr2) {
checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
checkStr(adr1.locality, adr2.locality, "Same locality");
checkStr(adr1.region, adr2.region, "Same region");
checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
checkStr(adr1.countryName, adr2.countryName, "Same countryName");
}
function checkContacts(contact1, contact2) {
checkStr(contact1.name, contact2.name, "Same name");
checkStr(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
checkStr(contact1.givenName, contact2.givenName, "Same givenName");
checkStr(contact1.additionalName, contact2.additionalName, "Same additionalName");
checkStr(contact1.familyName, contact2.familyName, "Same familyName");
checkStr(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
checkStr(contact1.nickname, contact2.nickname, "Same nickname");
checkStr(contact1.email, contact2.email, "Same email");
checkStr(contact1.photo, contact2.photo, "Same photo");
checkStr(contact1.url, contact2.url, "Same url");
checkStr(contact1.category, contact2.category, "Same category");
is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
checkStr(contact1.note, contact2.note, "Same note");
checkStr(contact1.impp, contact2.impp, "Same impp");
is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
is(contact1.sex, contact2.sex, "Same sex");
is(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
for (var i in contact1.adr)
checkAddress(contact1.adr[i], contact2.adr[i]);
}
var req;
var index = 0;
var mozContacts = window.navigator.mozContacts
var steps = [
function () {
ok(true, "Deleting database");
req = mozContacts.clear();
req.onsuccess = function () {
ok(true, "Deleted the database");
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({});
req.onsuccess = function () {
ok(req.result.length == 0, "Empty database is empty.");
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Adding empty contact");
createResult1 = new mozContact();
createResult1.init({});
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
sample_id1 = createResult1.id;
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({});
req.onsuccess = function () {
ok(req.result.length == 1, "One contact.");
findResult1 = req.result[0];
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Deleting empty contact");
req = navigator.mozContacts.remove(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find({});
req2.onsuccess = function () {
ok(req2.result.length == 0, "Empty Database.");
clearTemps();
next();
}
req2.onerror = onFailure;
}
req.onerror = onFailure;
},
function () {
ok(true, "Adding a new contact1");
createResult1 = new mozContact();
createResult1.init(properties1);
req = navigator.mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
sample_id1 = createResult1.id;
checkContacts(properties1, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({});
req.onsuccess = function() {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, findResult1);
ok(findResult1.updated, "Has updated field");
ok(findResult1.published, "Has published field");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Modifying contact1");
findResult1.impp = properties1.impp = (["phil impp"]);
req = navigator.mozContacts.save(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find({});
req2.onsuccess = function() {
ok(req2.result.length == 1, "Found exactly 1 contact.");
findResult2 = req2.result[0];
ok(findResult2.id == sample_id1, "Same ID");
checkContacts(findResult2, properties1);
ok(findResult2.impp.length == 1, "Found exactly 1 IMS info.");
next();
};
req2.onerror = onFailure;
};
req.onerror = onFailure;
},
function() {
ok(true, "Saving old contact, should abort!");
req = mozContacts.save(createResult1);
req.onsuccess = onUnwantedSuccess;
req.onerror = function() { ok(true, "Successfully declined updating old contact!"); next(); };
},
function() {
ok(true, "Saving old contact, should abort!");
req = mozContacts.save(findResult1)
req.onsuccess = onUnwantedSuccess;
req.onerror = function() { ok(true, "Successfully declined updating old contact!"); next(); };
},
function () {
ok(true, "Retrieving a specific contact by ID");
var options = {filterBy: ["id"],
filterOp: "equals",
filterValue: sample_id1};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(createResult1, properties1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving a specific contact by givenName");
var options = {filterBy: ["givenName"],
filterOp: "equals",
filterValue: properties1.givenName[0]};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(findResult1, createResult1);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Modifying contact2");
findResult1.impp = properties1.impp = (["phil impp"]);
req = mozContacts.save(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find({});
req2.onsuccess = function () {
ok(req2.result.length == 1, "Found exactly 1 contact.");
findResult1 = req2.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(findResult1, createResult1);
ok(findResult1.impp.length == 1, "Found exactly 1 IMS info.");
next();
}
req2.onerror = onFailure;
};
req.onerror = onFailure;
},
function () {
ok(true, "Searching contacts by query");
var options = {filterBy: ["name", "email"],
filterOp: "icontains",
filterValue: properties1.name[0].substring(0,4)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(findResult1, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Searching contacts by query");
var options = {filterBy: ["nickname", "email"],
filterOp: "icontains",
filterValue: properties1.nickname};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(findResult1, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Searching contacts with multiple indices");
var options = {filterBy: ["nickname", "email", "name"],
filterOp: "equals",
filterValue: properties1.nickname};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(findResult1, createResult1);
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Modifying contact3");
findResult1.email = (properties1.nickname);
findResult1.nickname = "TEST";
var newContact = new mozContact();
newContact.init(findResult1);
req = mozContacts.save(newContact);
req.onsuccess = function () {
var options = {filterBy: ["nickname", "email", "name"],
filterOp: "equals",
filterValue: properties1.nickname};
// One contact has it in nickname and the other in email
var req2 = mozContacts.find(options);
req2.onsuccess = function () {
ok(req2.result.length == 2, "Found exactly 2 contacts.");
ok(req2.result[0].id != req2.result[1].id, "Different ID");
next();
}
req2.onerror = onFailure;
};
req.onerror = onFailure;
},
function () {
ok(true, "Deleting contact" + findResult1.id);
req = mozContacts.remove(findResult1);
req.onsuccess = function () {
var req2 = mozContacts.find({});
req2.onsuccess = function () {
ok(req2.result.length == 1, "One contact left.");
findResult1 = req2.result[0];
next();
}
req2.onerror = onFailure;
}
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.remove(findResult1);
req.onsuccess = function () {
clearTemps();
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Adding a new contact");
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1)
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
sample_id1 = createResult1.id;
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Adding a new contact2");
createResult2 = new mozContact();
createResult2.init(properties2);
req = mozContacts.save(createResult2);
req.onsuccess = function () {
ok(createResult2.id, "The contact now has an ID.");
sample_id2 = createResult2.id;
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({})
req.onsuccess = function () {
ok(req.result.length == 2, "Found exactly 2 contact.");
next();
}
req.onerror = onFailure;
},
function () {
console.log("Searching contacts by query1");
var options = {filterBy: ["name", "email"],
filterOp: "icontains",
filterValue: properties1.name[0].substring(0, 4)}
req = mozContacts.find(options)
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id1, "Same ID");
checkContacts(findResult1, createResult1);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Searching contacts by query2");
var options = {filterBy: ["name", "email"],
filterOp: "icontains",
filterValue: properties2.name[0].substring(0, 4)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.adr.length == 2, "Adr length 2");
checkContacts(findResult1, createResult2);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Searching contacts by tel");
var options = {filterBy: ["tel"],
filterOp: "contains",
filterValue: properties2.tel[0].substring(0, 7)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id2, "Same ID");
checkContacts(findResult1, createResult2);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Searching contacts by email");
var options = {filterBy: ["email"],
filterOp: "contains",
filterValue: properties2.email[0].substring(0, 4)};
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 1, "Found exactly 1 contact.");
findResult1 = req.result[0];
ok(findResult1.id == sample_id2, "Same ID");
checkContacts(findResult1, createResult2);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear();
req.onsuccess = function () {
clearTemps();
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Adding 100 contacts");
for (var i=0; i<99; i++) {
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
};
req.onerror = onFailure;
};
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
ok(createResult1.name == properties1.name, "Same Name");
next();
};
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
req = mozContacts.find({});
req.onsuccess = function () {
ok(req.result.length == 100, "100 Entries.");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts with limit 10");
var options = { filterLimit: 10 };
req = mozContacts.find(options);
req.onsuccess = function () {
ok(req.result.length == 10, "10 Entries.");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts2");
var options = {filterBy: ["name"],
filterOp: "icontains",
filterValue: properties2.name[0].substring(0, 4)};
req = mozContacts.find({});
req.onsuccess = function () {
ok(req.result.length == 100, "100 Entries.");
checkContacts(createResult1, req.result[99]);
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear();
req.onsuccess = function () {
clearTemps();
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Testing clone contact");
createResult1 = new mozContact();
createResult1.init(properties1);
req = mozContacts.save(createResult1);
req.onsuccess = function () {
ok(createResult1.id, "The contact now has an ID.");
ok(createResult1.name == properties1.name, "Same Name");
next();
}
req.onerror = onFailure;
},
function() {
ok(true, "Testing clone contact2");
var cloned = new mozContact(createResult1);
ok(cloned.id != createResult1.id, "Cloned contact has new ID");
cloned.email = "new email!";
cloned.givenName = "Tom";
req = mozContacts.save(cloned);
req.onsuccess = function () {
ok(cloned.id, "The contact now has an ID.");
ok(cloned.email == "new email!", "Same Email");
ok(createResult1.email != cloned.email, "Clone has different email");
ok(cloned.givenName == "Tom", "New Name");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Retrieving all contacts");
var options = {filterBy: ["name"],
filterOp: "icontains",
filterValue: properties2.name[0].substring(0, 4)};
req = mozContacts.find({});
req.onsuccess = function () {
ok(req.result.length == 2, "2 Entries.");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "Search with redundant fields should only return 1 contact");
createResult1 = new mozContact();
createResult1.init({name: "XXX", nickname: "XXX", email: "XXX", tel: "XXX"});
req = mozContacts.save(createResult1);
req.onsuccess = function() {
var options = {filterBy: [],
filterOp: "equals",
filterValue: "XXX"};
var req2 = mozContacts.find(options);
req2.onsuccess = function() {
ok(req2.result.length == 1, "1 Entry");
next();
}
req2.onerror = onFailure;
}
req.onerror = onFailure;
},
function () {
ok(true, "Deleting database");
req = mozContacts.clear()
req.onsuccess = function () {
ok(true, "Deleted the database");
next();
}
req.onerror = onFailure;
},
function () {
ok(true, "all done!\n");
clearTemps();
SimpleTest.finish();
}
];
function next() {
ok(true, "Begin!");
if (index >= steps.length) {
ok(false, "Shouldn't get here!");
return;
}
try {
steps[index]();
} catch(ex) {
ok(false, "Caught exception", ex);
}
index += 1;
}
function permissionTest() {
if (gContactsEnabled) {
next();
} else {
is(mozContacts, null, "mozContacts is null when not enabled.");
SimpleTest.finish();
}
}
var gContactsEnabled = SpecialPowers.getBoolPref("dom.mozContacts.enabled");
SimpleTest.waitForExplicitFinish();
addLoadEvent(permissionTest);
ok(true, "test passed");
</script>
</pre>
</body>
</html>

View File

@ -4,6 +4,7 @@ DOM_SRCDIRS = \
dom/power \
dom/network/src \
dom/sms/src \
dom/contacts \
dom/src/events \
dom/src/storage \
dom/src/offline \

View File

@ -266,6 +266,14 @@ IDBCursor::CreateCommon(IDBRequest* aRequest,
cursor->mOwner = database->GetOwner();
cursor->mScriptOwner = database->GetScriptOwner();
if (cursor->mScriptOwner) {
if (NS_FAILED(NS_HOLD_JS_OBJECTS(cursor, IDBCursor))) {
return nsnull;
}
cursor->mRooted = true;
}
cursor->mRequest = aRequest;
cursor->mTransaction = aTransaction;
cursor->mObjectStore = aObjectStore;

View File

@ -164,7 +164,9 @@ IDBDatabase::Create(IDBWrapperCache* aOwnerCache,
db->mScriptContext = aOwnerCache->GetScriptContext();
db->mOwner = aOwnerCache->GetOwner();
db->mScriptOwner = aOwnerCache->GetScriptOwner();
if (!db->SetScriptOwner(aOwnerCache->GetScriptOwner())) {
return nsnull;
}
db->mDatabaseId = databaseInfo->id;
db->mName = databaseInfo->name;

View File

@ -138,7 +138,7 @@ GetKeyFromJSValOrThrow(JSContext* aCx,
JSBool
MakeOnlyKeyRange(JSContext* aCx,
uintN aArgc,
unsigned aArgc,
jsval* aVp)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -159,7 +159,7 @@ MakeOnlyKeyRange(JSContext* aCx,
JSBool
MakeLowerBoundKeyRange(JSContext* aCx,
uintN aArgc,
unsigned aArgc,
jsval* aVp)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -181,7 +181,7 @@ MakeLowerBoundKeyRange(JSContext* aCx,
JSBool
MakeUpperBoundKeyRange(JSContext* aCx,
uintN aArgc,
unsigned aArgc,
jsval* aVp)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -203,7 +203,7 @@ MakeUpperBoundKeyRange(JSContext* aCx,
JSBool
MakeBoundKeyRange(JSContext* aCx,
uintN aArgc,
unsigned aArgc,
jsval* aVp)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");

View File

@ -88,7 +88,9 @@ IDBRequest::Create(nsISupports* aSource,
request->mTransaction = aTransaction;
request->mScriptContext = aOwnerCache->GetScriptContext();
request->mOwner = aOwnerCache->GetOwner();
request->mScriptOwner = aOwnerCache->GetScriptOwner();
if (!request->SetScriptOwner(aOwnerCache->GetScriptOwner())) {
return nsnull;
}
return request.forget();
}
@ -129,7 +131,7 @@ IDBRequest::NotifyHelperCompleted(HelperBase* aHelper)
// Otherwise we need to get the result from the helper.
JSContext* cx;
if (mScriptOwner) {
if (GetScriptOwner()) {
nsIThreadJSContextStack* cxStack = nsContentUtils::ThreadJSContextStack();
NS_ASSERTION(cxStack, "Failed to get thread context stack!");
@ -317,7 +319,9 @@ IDBOpenDBRequest::Create(nsIScriptContext* aScriptContext,
request->mScriptContext = aScriptContext;
request->mOwner = aOwner;
request->mScriptOwner = aScriptOwner;
if (!request->SetScriptOwner(aScriptOwner)) {
return nsnull;
}
return request.forget();
}

View File

@ -119,7 +119,9 @@ IDBTransaction::Create(IDBDatabase* aDatabase,
transaction->mScriptContext = aDatabase->GetScriptContext();
transaction->mOwner = aDatabase->GetOwner();
transaction->mScriptOwner = aDatabase->GetScriptOwner();
if (!transaction->SetScriptOwner(aDatabase->GetScriptOwner())) {
return nsnull;
}
transaction->mDatabase = aDatabase;
transaction->mMode = aMode;

View File

@ -5,6 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "IDBWrapperCache.h"
#include "nsContentUtils.h"
USING_INDEXEDDB_NAMESPACE
@ -18,7 +19,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBWrapperCache,
nsDOMEventTargetHelper)
tmp->mScriptOwner = nsnull;
if (tmp->mScriptOwner) {
NS_DROP_JS_OBJECTS(tmp, IDBWrapperCache);
tmp->mScriptOwner = nsnull;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBWrapperCache,
@ -36,3 +40,36 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(IDBWrapperCache, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(IDBWrapperCache, nsDOMEventTargetHelper)
IDBWrapperCache::~IDBWrapperCache()
{
if (mScriptOwner) {
NS_DROP_JS_OBJECTS(this, IDBWrapperCache);
}
}
bool
IDBWrapperCache::SetScriptOwner(JSObject* aScriptOwner)
{
if (!aScriptOwner) {
NS_ASSERTION(!mScriptOwner,
"Don't null out existing owner, we need to call "
"DropJSObjects!");
return true;
}
mScriptOwner = aScriptOwner;
nsISupports* thisSupports = NS_CYCLE_COLLECTION_UPCAST(this, IDBWrapperCache);
nsXPCOMCycleCollectionParticipant* participant;
CallQueryInterface(this, &participant);
nsresult rv = nsContentUtils::HoldJSObjects(thisSupports, participant);
if (NS_FAILED(rv)) {
NS_WARNING("nsContentUtils::HoldJSObjects failed.");
mScriptOwner = nsnull;
return false;
}
return true;
}

Some files were not shown because too many files have changed in this diff Show More