Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2012-09-20 21:35:12 -04:00
commit 17dd80d158
22 changed files with 423 additions and 150 deletions

View File

@ -831,6 +831,69 @@ CssLogic.getShortNamePath = function CssLogic_getShortNamePath(aElement)
return reply;
};
/**
* Get a string list of selectors for a given CSSStyleRule.selectorText
*
* @param {string} aSelectorText The CSSStyleRule.selectorText to parse.
* @return {array} An array of string selectors.
*/
CssLogic.getSelectors = function CssLogic_getSelectors(aSelectorText)
{
let selectors = [];
let selector = aSelectorText.trim();
if (!selector) {
return selectors;
}
let nesting = 0;
let currentSelector = [];
// Parse a selector group into selectors. Normally we could just .split(',')
// however Gecko allows -moz-any(a, b, c) as a selector so we ignore commas
// inside brackets.
for (let i = 0, selLen = selector.length; i < selLen; i++) {
let c = selector.charAt(i);
switch (c) {
case ",":
if (nesting == 0 && currentSelector.length > 0) {
let selectorStr = currentSelector.join("").trim();
if (selectorStr) {
selectors.push(selectorStr);
}
currentSelector = [];
} else {
currentSelector.push(c);
}
break;
case "(":
nesting++;
currentSelector.push(c);
break;
case ")":
nesting--;
currentSelector.push(c);
break;
default:
currentSelector.push(c);
break;
}
}
// Add the last selector.
if (nesting == 0 && currentSelector.length > 0) {
let selectorStr = currentSelector.join("").trim();
if (selectorStr) {
selectors.push(selectorStr);
}
}
return selectors;
}
/**
* Memonized lookup of a l10n string from a string bundle.
* @param {string} aName The key to lookup.
@ -1268,56 +1331,8 @@ CssRule.prototype = {
return this._selectors;
}
let selector = this._domRule.selectorText.trim();
if (!selector) {
return this._selectors;
}
let nesting = 0;
let currentSelector = [];
// Parse a selector group into selectors. Normally we could just .split(',')
// however Gecko allows -moz-any(a, b, c) as a selector so we ignore commas
// inside brackets.
for (let i = 0, selLen = selector.length; i < selLen; i++) {
let c = selector.charAt(i);
switch (c) {
case ",":
if (nesting == 0 && currentSelector.length > 0) {
let selectorStr = currentSelector.join("").trim();
if (selectorStr) {
this._selectors.push(new CssSelector(this, selectorStr));
}
currentSelector = [];
} else {
currentSelector.push(c);
}
break;
case "(":
nesting++;
currentSelector.push(c);
break;
case ")":
nesting--;
currentSelector.push(c);
break;
default:
currentSelector.push(c);
break;
}
}
// Add the last selector.
if (nesting == 0 && currentSelector.length > 0) {
let selectorStr = currentSelector.join("").trim();
if (selectorStr) {
this._selectors.push(new CssSelector(this, selectorStr));
}
}
let selectors = CssLogic.getSelectors(this._domRule.selectorText);
this._selectors = [new CssSelector(this, text) for (text of selectors)];
return this._selectors;
},

View File

@ -1404,7 +1404,34 @@ RuleEditor.prototype = {
*/
populate: function RuleEditor_populate()
{
this.selectorText.textContent = this.rule.selectorText;
// Clear out existing viewers.
while (this.selectorText.hasChildNodes()) {
this.selectorText.removeChild(this.selectorText.lastChild);
}
// If selector text comes from a css rule, highlight selectors that
// actually match. For custom selector text (such as for the 'element'
// style, just show the text directly.
if (this.rule.domRule && this.rule.domRule.selectorText) {
let selectors = CssLogic.getSelectors(this.rule.selectorText);
let element = this.rule.inherited || this.ruleView._viewedElement;
for (let i = 0; i < selectors.length; i++) {
let selector = selectors[i];
if (i != 0) {
createChild(this.selectorText, "span", {
class: "ruleview-selector-separator",
textContent: ", "
});
}
let cls = element.mozMatchesSelector(selector) ? "ruleview-selector-matched" : "ruleview-selector-unmatched";
createChild(this.selectorText, "span", {
class: cls,
textContent: selector
});
}
} else {
this.selectorText.textContent = this.rule.selectorText;
}
for (let prop of this.rule.textProps) {
if (!prop.editor) {

View File

@ -31,7 +31,7 @@ function startTest()
'#testid {' +
' background-color: blue;' +
'} ' +
'.testclass {' +
'.testclass, .unmatched {' +
' background-color: green;' +
'}';
@ -55,6 +55,10 @@ function startTest()
is(ruleView.element.querySelectorAll("#noResults").length, 1, "After highlighting null, has a no-results element again.");
ruleView.highlight(testElement);
let classEditor = ruleView.element.children[2]._ruleEditor;
is(classEditor.selectorText.querySelector(".ruleview-selector-matched").textContent, ".testclass", ".textclass should be matched.");
is(classEditor.selectorText.querySelector(".ruleview-selector-unmatched").textContent, ".unmatched", ".unmatched should not be matched.");
waitForFocus(testCancelNew, ruleDialog);
}, true);
}

View File

@ -281,3 +281,7 @@
.ruleview-propertycontainer:hover > .ruleview-propertyvalue {
border-bottom-color: hsl(0,0%,50%);
}
.ruleview-selector-separator, .ruleview-selector-unmatched {
color: #888;
}

View File

@ -283,3 +283,8 @@
.ruleview-propertycontainer:hover > .ruleview-propertyvalue {
border-bottom-color: hsl(0,0%,50%);
}
.ruleview-selector-separator, .ruleview-selector-unmatched {
color: #888;
}

View File

@ -283,3 +283,7 @@
.ruleview-propertycontainer:hover > .ruleview-propertyvalue {
border-bottom-color: hsl(0,0%,50%);
}
.ruleview-selector-separator, .ruleview-selector-unmatched {
color: #888;
}

View File

@ -1575,6 +1575,10 @@ nsINode::ReplaceOrInsertBefore(bool aReplace, nsINode* aNewChild,
if (nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
static_cast<nsGenericElement*>(aNewChild)->FireNodeRemovedForChildren();
}
// Verify that our aRefChild is still sensible
if (aRefChild && aRefChild->GetNodeParent() != this) {
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
}
nsIDocument* doc = OwnerDoc();

View File

@ -61,7 +61,7 @@ nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
InputContextAction::LOST_FOCUS);
SetIMEState(newState, nullptr, widget, action);
}
sContent = nullptr;
NS_IF_RELEASE(sContent);
sPresContext = nullptr;
OnTextStateBlur(nullptr, nullptr);
return NS_OK;
@ -89,7 +89,7 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
SetIMEState(newState, nullptr, widget, action);
}
sContent = nullptr;
NS_IF_RELEASE(sContent);
sPresContext = nullptr;
return NS_OK;
@ -172,7 +172,10 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
SetIMEState(newState, aContent, widget, aAction);
sPresContext = aPresContext;
sContent = aContent;
if (sContent != aContent) {
NS_IF_RELEASE(sContent);
NS_IF_ADDREF(sContent = aContent);
}
return NS_OK;
}

View File

@ -4453,13 +4453,9 @@ nsDocShell::Reload(uint32_t aReloadFlags)
nsCOMPtr<nsISHistory> rootSH;
rv = GetRootSessionHistory(getter_AddRefs(rootSH));
nsCOMPtr<nsISHistoryInternal> shistInt(do_QueryInterface(rootSH));
bool canReload = true;
bool canReload = true;
if (rootSH) {
nsCOMPtr<nsISHistoryListener> listener;
shistInt->GetListener(getter_AddRefs(listener));
if (listener) {
listener->OnHistoryReload(mCurrentURI, aReloadFlags, &canReload);
}
shistInt->NotifyOnHistoryReload(mCurrentURI, aReloadFlags, &canReload);
}
if (!canReload)

View File

@ -24,7 +24,7 @@ struct nsTArrayDefaultAllocator;
[ref] native nsDocshellIDArray(nsTArray<uint64_t, nsTArrayDefaultAllocator>);
[scriptable, uuid(e27cf38e-c19f-4294-bd31-d7e0916e7fa2)]
[scriptable, uuid(f9348014-0239-11e2-b029-3d38e719eb2d)]
interface nsISHistoryInternal: nsISupports
{
/**
@ -58,10 +58,17 @@ interface nsISHistoryInternal: nsISupports
*/
void replaceEntry(in long aIndex, in nsISHEntry aReplaceEntry);
/**
* Get handle to the history listener
/**
* Notifies all registered session history listeners about an impending
* reload.
*
* @param aReloadURI The URI of the document to be reloaded.
* @param aReloadFlags Flags that indicate how the document is to be
* refreshed. See constants on the nsIWebNavigation
* interface.
* @return Whether the operation can proceed.
*/
readonly attribute nsISHistoryListener listener;
boolean notifyOnHistoryReload(in nsIURI aReloadURI, in unsigned long aReloadFlags);
/**
* Evict content viewers which don't lie in the "safe" range around aIndex.

View File

@ -96,6 +96,48 @@ static PRLogModuleInfo* gLogModule = PR_LOG_DEFINE("nsSHistory");
} \
PR_END_MACRO
// Iterates over all registered session history listeners.
#define ITERATE_LISTENERS(body) \
PR_BEGIN_MACRO \
{ \
nsAutoTObserverArray<nsWeakPtr, 2>::EndLimitedIterator \
iter(mListeners); \
while (iter.HasMore()) { \
nsCOMPtr<nsISHistoryListener> listener = \
do_QueryReferent(iter.GetNext()); \
if (listener) { \
body; \
} \
} \
} \
PR_END_MACRO
// Calls a given method on all registered session history listeners.
#define NOTIFY_LISTENERS(method, args) \
ITERATE_LISTENERS( \
listener->method args; \
);
// Calls a given method on all registered session history listeners.
// Listeners may return 'false' to cancel an action so make sure that we
// set the return value to 'false' if one of the listeners wants to cancel.
#define NOTIFY_LISTENERS_CANCELABLE(method, retval, args) \
PR_BEGIN_MACRO \
{ \
bool canceled = false; \
retval = true; \
ITERATE_LISTENERS( \
listener->method args; \
if (!retval) { \
canceled = true; \
} \
); \
if (canceled) { \
retval = false; \
} \
} \
PR_END_MACRO
enum HistCmd{
HIST_CMD_BACK,
HIST_CMD_FORWARD,
@ -370,22 +412,17 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist)
nsCOMPtr<nsISHTransaction> txn(do_CreateInstance(NS_SHTRANSACTION_CONTRACTID));
NS_ENSURE_TRUE(txn, NS_ERROR_FAILURE);
// Notify any listener about the new addition
if (mListener) {
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
if (listener) {
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aSHEntry));
if (hEntry) {
int32_t currentIndex = mIndex;
hEntry->GetURI(getter_AddRefs(uri));
listener->OnHistoryNewEntry(uri);
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIHistoryEntry> hEntry(do_QueryInterface(aSHEntry));
if (hEntry) {
int32_t currentIndex = mIndex;
hEntry->GetURI(getter_AddRefs(uri));
NOTIFY_LISTENERS(OnHistoryNewEntry, (uri));
// If a listener has changed mIndex, we need to get currentTxn again,
// otherwise we'll be left at an inconsistent state (see bug 320742)
if (currentIndex != mIndex)
GetTransactionAtIndex(mIndex, getter_AddRefs(currentTxn));
}
// If a listener has changed mIndex, we need to get currentTxn again,
// otherwise we'll be left at an inconsistent state (see bug 320742)
if (currentIndex != mIndex) {
GetTransactionAtIndex(mIndex, getter_AddRefs(currentTxn));
}
}
@ -622,13 +659,8 @@ nsSHistory::PurgeHistory(int32_t aEntries)
aEntries = NS_MIN(aEntries, mLength);
bool purgeHistory = true;
// Notify the listener about the history purge
if (mListener) {
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
if (listener) {
listener->OnHistoryPurge(aEntries, &purgeHistory);
}
}
NOTIFY_LISTENERS_CANCELABLE(OnHistoryPurge, purgeHistory,
(aEntries, &purgeHistory));
if (!purgeHistory) {
// Listener asked us not to purge
@ -674,8 +706,9 @@ nsSHistory::AddSHistoryListener(nsISHistoryListener * aListener)
// have the right ownership with who ever listens to SHistory
nsWeakPtr listener = do_GetWeakReference(aListener);
if (!listener) return NS_ERROR_FAILURE;
mListener = listener;
return NS_OK;
return mListeners.AppendElementUnlessExists(listener) ?
NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -684,12 +717,9 @@ nsSHistory::RemoveSHistoryListener(nsISHistoryListener * aListener)
{
// Make sure the listener that wants to be removed is the
// one we have in store.
nsWeakPtr listener = do_GetWeakReference(aListener);
if (listener == mListener) {
mListener = nullptr;
return NS_OK;
}
return NS_ERROR_FAILURE;
nsWeakPtr listener = do_GetWeakReference(aListener);
mListeners.RemoveElement(listener);
return NS_OK;
}
@ -717,14 +747,12 @@ nsSHistory::ReplaceEntry(int32_t aIndex, nsISHEntry * aReplaceEntry)
return rv;
}
/* Get a handle to the Session history listener */
NS_IMETHODIMP
nsSHistory::GetListener(nsISHistoryListener ** aListener)
nsSHistory::NotifyOnHistoryReload(nsIURI* aReloadURI, uint32_t aReloadFlags,
bool* aCanReload)
{
NS_ENSURE_ARG_POINTER(aListener);
if (mListener)
CallQueryReferent(mListener.get(), aListener);
// Don't addref aListener. It is a weak pointer.
NOTIFY_LISTENERS_CANCELABLE(OnHistoryReload, *aCanReload,
(aReloadURI, aReloadFlags, aCanReload));
return NS_OK;
}
@ -842,20 +870,15 @@ nsSHistory::Reload(uint32_t aReloadFlags)
loadType = nsIDocShellLoadInfo::loadReloadNormal;
}
// Notify listeners
// We are reloading. Send Reload notifications.
// nsDocShellLoadFlagType is not public, where as nsIWebNavigation
// is public. So send the reload notifications with the
// nsIWebNavigation flags.
bool canNavigate = true;
if (mListener) {
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
// We are reloading. Send Reload notifications.
// nsDocShellLoadFlagType is not public, where as nsIWebNavigation
// is public. So send the reload notifications with the
// nsIWebNavigation flags.
if (listener) {
nsCOMPtr<nsIURI> currentURI;
rv = GetCurrentURI(getter_AddRefs(currentURI));
listener->OnHistoryReload(currentURI, aReloadFlags, &canNavigate);
}
}
nsCOMPtr<nsIURI> currentURI;
rv = GetCurrentURI(getter_AddRefs(currentURI));
NOTIFY_LISTENERS_CANCELABLE(OnHistoryReload, canNavigate,
(currentURI, aReloadFlags, &canNavigate));
if (!canNavigate)
return NS_OK;
@ -867,14 +890,10 @@ nsSHistory::ReloadCurrentEntry()
{
// Notify listeners
bool canNavigate = true;
if (mListener) {
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
if (listener) {
nsCOMPtr<nsIURI> currentURI;
GetCurrentURI(getter_AddRefs(currentURI));
listener->OnHistoryGotoIndex(mIndex, currentURI, &canNavigate);
}
}
nsCOMPtr<nsIURI> currentURI;
GetCurrentURI(getter_AddRefs(currentURI));
NOTIFY_LISTENERS_CANCELABLE(OnHistoryGotoIndex, canNavigate,
(mIndex, currentURI, &canNavigate));
if (!canNavigate)
return NS_OK;
@ -1515,22 +1534,18 @@ nsSHistory::LoadEntry(int32_t aIndex, long aLoadType, uint32_t aHistCmd)
nsCOMPtr<nsIURI> nextURI;
nHEntry->GetURI(getter_AddRefs(nextURI));
if(mListener) {
nsCOMPtr<nsISHistoryListener> listener(do_QueryReferent(mListener));
if (listener) {
if (aHistCmd == HIST_CMD_BACK) {
// We are going back one entry. Send GoBack notifications
listener->OnHistoryGoBack(nextURI, &canNavigate);
}
else if (aHistCmd == HIST_CMD_FORWARD) {
// We are going forward. Send GoForward notification
listener->OnHistoryGoForward(nextURI, &canNavigate);
}
else if (aHistCmd == HIST_CMD_GOTOINDEX) {
// We are going somewhere else. This is not reload either
listener->OnHistoryGotoIndex(aIndex, nextURI, &canNavigate);
}
}
if (aHistCmd == HIST_CMD_BACK) {
// We are going back one entry. Send GoBack notifications
NOTIFY_LISTENERS_CANCELABLE(OnHistoryGoBack, canNavigate,
(nextURI, &canNavigate));
} else if (aHistCmd == HIST_CMD_FORWARD) {
// We are going forward. Send GoForward notification
NOTIFY_LISTENERS_CANCELABLE(OnHistoryGoForward, canNavigate,
(nextURI, &canNavigate));
} else if (aHistCmd == HIST_CMD_GOTOINDEX) {
// We are going somewhere else. This is not reload either
NOTIFY_LISTENERS_CANCELABLE(OnHistoryGotoIndex, canNavigate,
(aIndex, nextURI, &canNavigate));
}
if (!canNavigate) {

View File

@ -19,7 +19,7 @@
#include "nsISimpleEnumerator.h"
#include "nsISHistoryListener.h"
#include "nsIHistoryEntry.h"
#include "nsIObserver.h"
#include "nsTObserverArray.h"
// Needed to maintain global list of all SHistory objects
#include "prclist.h"
@ -91,8 +91,8 @@ protected:
int32_t mIndex;
int32_t mLength;
int32_t mRequestedIndex;
// Session History listener
nsWeakPtr mListener;
// Session History listeners
nsAutoTObserverArray<nsWeakPtr, 2> mListeners;
// Weak reference. Do not refcount this.
nsIDocShell * mRootDocShell;

View File

@ -20,6 +20,7 @@ MOCHITEST_BROWSER_FILES = \
browser_bug441169.js \
browser_bug420605.js \
file_bug420605.html \
browser_bug422543.js \
browser_bug503832.js \
browser_loadDisallowInherit.js \
file_bug503832.html \

View File

@ -0,0 +1,172 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
function SHistoryListener() {
}
SHistoryListener.prototype = {
retval: true,
last: "initial",
OnHistoryNewEntry: function (aNewURI) {
this.last = "newentry";
},
OnHistoryGoBack: function (aBackURI) {
this.last = "goback";
return this.retval;
},
OnHistoryGoForward: function (aForwardURI) {
this.last = "goforward";
return this.retval;
},
OnHistoryGotoIndex: function (aIndex, aGotoURI) {
this.last = "gotoindex";
return this.retval;
},
OnHistoryPurge: function (aNumEntries) {
this.last = "purge";
return this.retval;
},
OnHistoryReload: function (aReloadURI, aReloadFlags) {
this.last = "reload";
return this.retval;
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener,
Ci.nsISupportsWeakReference])
};
let gFirstListener = new SHistoryListener();
let gSecondListener = new SHistoryListener();
function test() {
TestRunner.run();
}
function runTests() {
yield setup();
let browser = gBrowser.selectedBrowser;
checkListeners("initial", "listeners initialized");
// Check if all history listeners are always notified.
info("# part 1");
browser.loadURI("http://www.example.com/");
yield whenPageShown(browser);
checkListeners("newentry", "shistory has a new entry");
ok(browser.canGoBack, "we can go back");
browser.goBack();
yield whenPageShown(browser);
checkListeners("goback", "back to the first shentry");
ok(browser.canGoForward, "we can go forward");
browser.goForward();
yield whenPageShown(browser);
checkListeners("goforward", "forward to the second shentry");
browser.reload();
yield whenPageShown(browser);
checkListeners("reload", "current shentry reloaded");
browser.gotoIndex(0);
yield whenPageShown(browser);
checkListeners("gotoindex", "back to the first index");
// Check nsISHistoryInternal.notifyOnHistoryReload
info("# part 2");
ok(notifyReload(), "reloading has not been canceled");
checkListeners("reload", "saw the reload notification");
// Let the first listener cancel the reload action.
info("# part 3");
resetListeners();
gFirstListener.retval = false;
ok(!notifyReload(), "reloading has been canceled");
checkListeners("reload", "saw the reload notification");
// Let both listeners cancel the reload action.
info("# part 4");
resetListeners();
gSecondListener.retval = false;
ok(!notifyReload(), "reloading has been canceled");
checkListeners("reload", "saw the reload notification");
// Let the second listener cancel the reload action.
info("# part 5");
resetListeners();
gFirstListener.retval = true;
ok(!notifyReload(), "reloading has been canceled");
checkListeners("reload", "saw the reload notification");
}
function checkListeners(aLast, aMessage) {
is(gFirstListener.last, aLast, aMessage);
is(gSecondListener.last, aLast, aMessage);
}
function resetListeners() {
gFirstListener.last = gSecondListener.last = "initial";
}
function notifyReload() {
let browser = gBrowser.selectedBrowser;
let shistory = browser.docShell.sessionHistory;
shistory.QueryInterface(Ci.nsISHistoryInternal);
return shistory.notifyOnHistoryReload(browser.currentURI, 0);
}
function setup(aCallback) {
let tab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla");
let browser = tab.linkedBrowser;
registerCleanupFunction(function () gBrowser.removeTab(tab));
whenPageShown(browser, function () {
gFirstListener = new SHistoryListener();
gSecondListener = new SHistoryListener();
let shistory = browser.docShell.sessionHistory;
shistory.addSHistoryListener(gFirstListener);
shistory.addSHistoryListener(gSecondListener);
registerCleanupFunction(function () {
shistory.removeSHistoryListener(gFirstListener);
shistory.removeSHistoryListener(gSecondListener);
});
(aCallback || TestRunner.next)();
});
}
function whenPageShown(aBrowser, aCallback) {
aBrowser.addEventListener("pageshow", function onLoad() {
aBrowser.removeEventListener("pageshow", onLoad, true);
executeSoon(aCallback || TestRunner.next);
}, true);
}
let TestRunner = {
run: function () {
waitForExplicitFinish();
this._iter = runTests();
this.next();
},
next: function () {
try {
TestRunner._iter.next();
} catch (e if e instanceof StopIteration) {
TestRunner.finish();
}
},
finish: function () {
finish();
}
};

View File

@ -39,8 +39,8 @@ struct EnumerationResponse
struct StatStorageResponse
{
int64_t totalBytes;
int64_t freeBytes;
int64_t totalBytes;
nsString mountState;
};

View File

@ -166,15 +166,15 @@ DeviceStorageTypeChecker::Check(const nsAString& aType, nsIFile* aFile)
extensionMatch.AppendLiteral(";");
if (aType.EqualsLiteral(DEVICESTORAGE_PICTURES)) {
return FindInReadable(extensionMatch, mPicturesExtensions);
return CaseInsensitiveFindInReadable(extensionMatch, mPicturesExtensions);
}
if (aType.EqualsLiteral(DEVICESTORAGE_VIDEOS)) {
return FindInReadable(extensionMatch, mVideosExtensions);
return CaseInsensitiveFindInReadable(extensionMatch, mVideosExtensions);
}
if (aType.EqualsLiteral(DEVICESTORAGE_MUSIC)) {
return FindInReadable(extensionMatch, mMusicExtensions);
return CaseInsensitiveFindInReadable(extensionMatch, mMusicExtensions);
}
return false;

View File

@ -71,7 +71,7 @@ var storage = navigator.getDeviceStorage("pictures");
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
var prefix = "devicestorage/" + randomFilename(12) + ".png"
var files = [ "a.png", "b.png", "c.png", "d/a.png", "d/b.png", "d/c.png", "d/d.png", "The/quick/brown/fox/jumps/over/the/lazy/dog.png"]
var files = [ "a.PNG", "b.pnG", "c.png", "d/a.png", "d/b.png", "d/c.png", "d/d.png", "The/quick/brown/fox/jumps/over/the/lazy/dog.png"]
var addedSoFar = 0;

View File

@ -21,7 +21,8 @@ class GeckoInstance(object):
profile = self.profile
if not profile:
prefs = {"marionette.defaultPrefs.enabled": True,
"marionette.defaultPrefs.port": 2828}
"marionette.defaultPrefs.port": 2828,
"browser.warnOnQuit": False}
profile = {"preferences": prefs, "restore":False}
print "starting runner"
self.runner = Runner.create(binary=self.bin, profile_args=profile, cmdargs=['-no-remote'])

View File

@ -131,7 +131,7 @@ class Marionette(object):
def __del__(self):
if self.emulator:
self.emulator.close()
if self.bin:
if self.instance:
self.instance.close()
for qemu in self.extra_emulators:
qemu.emulator.close()

View File

@ -219,7 +219,7 @@ class MarionetteJSTestCase(CommonTestCase):
self.loglines = self.marionette.get_logs()
raise
self.marionette.execute_script("log('TEST-END: %s');" % self.jsFile)
self.marionette.execute_script("log('TEST-END: %s');" % self.jsFile.replace('\\', '\\\\'))

View File

@ -78,6 +78,16 @@ class MarionetteTestResult(unittest._TextTestResult):
else:
self.perfdata.join_results(testcase.perfdata)
def printErrorList(self, flavour, errors):
for test, err in errors:
self.stream.writeln(self.separator1)
self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
self.stream.writeln(self.separator2)
errlines = err.strip().split('\n')
for line in errlines[0:-1]:
self.stream.writeln("%s" % line)
self.stream.writeln("TEST-UNEXPECTED-FAIL : %s" % errlines[-1])
class MarionetteTextTestRunner(unittest.TextTestRunner):
@ -327,6 +337,11 @@ class MarionetteTestRunner(object):
with open(self.xml_output, 'w') as f:
f.write(self.generate_xml(self.results))
if self.marionette.instance:
self.marionette.instance.close()
self.marionette.instance = None
del self.marionette
def run_test(self, test, testtype):
if not self.httpd:
print "starting httpd"

View File

@ -12,7 +12,7 @@ except (OSError, IOError):
# dependencies
deps = ['manifestdestiny', 'mozhttpd >= 0.3',
'mozprocess == 0.5', 'mozrunner == 5.10', 'datazilla == 0.2.1']
'mozprocess == 0.5', 'mozrunner == 5.10']
setup(name='marionette',
version=version,