mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
17dd80d158
@ -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;
|
||||
},
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -281,3 +281,7 @@
|
||||
.ruleview-propertycontainer:hover > .ruleview-propertyvalue {
|
||||
border-bottom-color: hsl(0,0%,50%);
|
||||
}
|
||||
|
||||
.ruleview-selector-separator, .ruleview-selector-unmatched {
|
||||
color: #888;
|
||||
}
|
||||
|
@ -283,3 +283,8 @@
|
||||
.ruleview-propertycontainer:hover > .ruleview-propertyvalue {
|
||||
border-bottom-color: hsl(0,0%,50%);
|
||||
}
|
||||
|
||||
.ruleview-selector-separator, .ruleview-selector-unmatched {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
|
@ -283,3 +283,7 @@
|
||||
.ruleview-propertycontainer:hover > .ruleview-propertyvalue {
|
||||
border-bottom-color: hsl(0,0%,50%);
|
||||
}
|
||||
|
||||
.ruleview-selector-separator, .ruleview-selector-unmatched {
|
||||
color: #888;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 \
|
||||
|
172
docshell/test/browser/browser_bug422543.js
Normal file
172
docshell/test/browser/browser_bug422543.js
Normal 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();
|
||||
}
|
||||
};
|
@ -39,8 +39,8 @@ struct EnumerationResponse
|
||||
|
||||
struct StatStorageResponse
|
||||
{
|
||||
int64_t totalBytes;
|
||||
int64_t freeBytes;
|
||||
int64_t totalBytes;
|
||||
nsString mountState;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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'])
|
||||
|
@ -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()
|
||||
|
@ -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('\\', '\\\\'))
|
||||
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user