Merge cvs-trunk-mirror to mozilla-central.

--HG--
rename : js/src/jsapi.c => js/src/jsapi.cpp
rename : js/src/jsarray.c => js/src/jsarray.cpp
rename : js/src/jsatom.c => js/src/jsatom.cpp
rename : js/src/jsdate.c => js/src/jsdate.cpp
rename : js/src/jsemit.c => js/src/jsemit.cpp
rename : js/src/jsgc.c => js/src/jsgc.cpp
rename : js/src/jsinterp.c => js/src/jsinterp.cpp
rename : js/src/jsnum.c => js/src/jsnum.cpp
rename : js/src/jsobj.c => js/src/jsobj.cpp
rename : js/src/jsopcode.c => js/src/jsopcode.cpp
rename : js/src/jsscope.c => js/src/jsscope.cpp
rename : js/src/jsstr.c => js/src/jsstr.cpp
rename : js/src/prmjtime.c => js/src/prmjtime.cpp
This commit is contained in:
benjamin@smedbergs.us 2008-02-27 11:33:49 -05:00
commit 8e65489719
618 changed files with 14022 additions and 12415 deletions

View File

@ -47,6 +47,8 @@ include $(topsrcdir)/config/config.mk
default alldep all::
$(RM) -rf $(DIST)/sdk
$(RM) -rf $(DIST)/include
$(RM) -rf $(DIST)/private
$(RM) -rf $(DIST)/public
$(RM) -rf _tests
TIERS += base
@ -138,6 +140,9 @@ endif # WINNT
ifeq ($(OS_ARCH),WINNT)
# we want to copy PDB files on Windows
MAKE_SYM_STORE_ARGS := -c
ifdef PDBSTR_PATH
MAKE_SYM_STORE_ARGS += -i
endif
ifeq (,$(CYGWIN_WRAPPER))
# this doesn't work with Cygwin Python
MAKE_SYM_STORE_ARGS += --vcs-info

View File

@ -44,8 +44,9 @@ interface nsIDocument;
interface nsIFrame;
interface nsObjectFrame;
interface nsIContent;
interface nsITimer;
[uuid(933f7472-cbe3-4d95-a77a-ce7ea3812b32)]
[uuid(27386cf1-f27e-4d2d-9bf4-c4621d50d299)]
interface nsIAccessibilityService : nsIAccessibleRetrieval
{
nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
@ -100,6 +101,17 @@ interface nsIAccessibilityService : nsIAccessibleRetrieval
void invalidateSubtreeFor(in nsIPresShell aPresShell,
in nsIContent aChangedContent,
in PRUint32 aEvent);
/**
* An internal doc load event has occured. Handle the event and remove it from the list.
* @param aTimer The timer created to handle this doc load event
* @param aClosure The nsIWebProgress* for the load event
* @param aEventType The type of load event, one of: nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START,
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE or
* nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED
*/
void processDocLoadEvent(in nsITimer aTimer, in voidPtr aClosure, in PRUint32 aEventType);
};

View File

@ -64,34 +64,28 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
{"alertdialog", nsIAccessibleRole::ROLE_ALERT, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"application", nsIAccessibleRole::ROLE_APPLICATION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"button", nsIAccessibleRole::ROLE_PUSHBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_pressed, kBoolState, nsIAccessibleStates::STATE_PRESSED},
{&nsAccessibilityAtoms::aria_pressed, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
{"checkbox", nsIAccessibleRole::ROLE_CHECKBUTTON, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"columnheader", nsIAccessibleRole::ROLE_COLUMNHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"combobox", nsIAccessibleRole::ROLE_COMBOBOX, eNameLabelOrTitle, eHasValueMinMax,
nsIAccessibleStates::STATE_COLLAPSED | nsIAccessibleStates::STATE_HASPOPUP,
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED}, kEndEntry},
{"description", nsIAccessibleRole::ROLE_TEXT_CONTAINER, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"dialog", nsIAccessibleRole::ROLE_DIALOG, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"document", nsIAccessibleRole::ROLE_DOCUMENT, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"grid", nsIAccessibleRole::ROLE_TABLE, eNameLabelOrTitle, eNoValue, nsIAccessibleStates::STATE_FOCUSABLE,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"gridcell", nsIAccessibleRole::ROLE_CELL, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED},
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
@ -101,13 +95,11 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
{"heading", nsIAccessibleRole::ROLE_HEADING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"img", nsIAccessibleRole::ROLE_GRAPHIC, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"label", nsIAccessibleRole::ROLE_LABEL, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"link", nsIAccessibleRole::ROLE_LINK, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_LINKED, kEndEntry},
{"list", nsIAccessibleRole::ROLE_LIST, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"listbox", nsIAccessibleRole::ROLE_LISTBOX, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"listitem", nsIAccessibleRole::ROLE_LISTITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
@ -116,60 +108,46 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
{"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"menu", nsIAccessibleRole::ROLE_MENUPOPUP, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"menubar", nsIAccessibleRole::ROLE_MENUBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"menuitem", nsIAccessibleRole::ROLE_MENUITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
{"menuitemcheckbox", nsIAccessibleRole::ROLE_CHECK_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED },
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED}, kEndEntry},
{"menuitemradio", nsIAccessibleRole::ROLE_RADIO_MENU_ITEM, eNameOkFromChildren, eNoValue, nsIAccessibleStates::STATE_CHECKABLE,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED }, kEndEntry},
{"option", nsIAccessibleRole::ROLE_OPTION, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "mixed", nsIAccessibleStates::STATE_MIXED | nsIAccessibleStates::STATE_CHECKABLE},
{&nsAccessibilityAtoms::aria_checked, "false", nsIAccessibleStates::STATE_CHECKABLE}, kEndEntry},
{"presentation", nsIAccessibleRole::ROLE_NOTHING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"progressbar", nsIAccessibleRole::ROLE_PROGRESSBAR, eNameLabelOrTitle, eHasValueMinMax, nsIAccessibleStates::STATE_READONLY, kEndEntry},
{"radio", nsIAccessibleRole::ROLE_RADIOBUTTON, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_checked, kBoolState, nsIAccessibleStates::STATE_CHECKED}, kEndEntry},
{"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"radiogroup", nsIAccessibleRole::ROLE_GROUPING, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"region", nsIAccessibleRole::ROLE_PANE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"row", nsIAccessibleRole::ROLE_ROW, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
{&nsAccessibilityAtoms::aria_expanded, "false", nsIAccessibleStates::STATE_COLLAPSED}, kEndEntry},
{"rowheader", nsIAccessibleRole::ROLE_ROWHEADER, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"section", nsIAccessibleRole::ROLE_SECTION, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"separator", nsIAccessibleRole::ROLE_SEPARATOR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"slider", nsIAccessibleRole::ROLE_SLIDER, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"spinbutton", nsIAccessibleRole::ROLE_SPINBUTTON, eNameLabelOrTitle, eHasValueMinMax, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"status", nsIAccessibleRole::ROLE_STATUSBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"tab", nsIAccessibleRole::ROLE_PAGETAB, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"tab", nsIAccessibleRole::ROLE_PAGETAB, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"tablist", nsIAccessibleRole::ROLE_PAGETABLIST, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"tabpanel", nsIAccessibleRole::ROLE_PROPERTYPAGE, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"textbox", nsIAccessibleRole::ROLE_ENTRY, eNameLabelOrTitle, eNoValue, kNoReqStates,
@ -177,21 +155,16 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
// Manually map EXT_STATE_SUPPORTS_AUTOCOMPLETION aria-autocomplete
{&nsAccessibilityAtoms::aria_autocomplete, "list", nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_autocomplete, "both", nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY}, kEndEntry},
{"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE}, kEndEntry},
{"toolbar", nsIAccessibleRole::ROLE_TOOLBAR, eNameLabelOrTitle, eNoValue, kNoReqStates, kEndEntry},
{"tooltip", nsIAccessibleRole::ROLE_TOOLTIP, eNameOkFromChildren, eNoValue, kNoReqStates, kEndEntry},
{"tree", nsIAccessibleRole::ROLE_OUTLINE, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"treegrid", nsIAccessibleRole::ROLE_TREE_TABLE, eNameLabelOrTitle, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_readonly, kBoolState, nsIAccessibleStates::STATE_READONLY},
{&nsAccessibilityAtoms::aria_multiselectable, kBoolState, nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE}, kEndEntry},
{"treeitem", nsIAccessibleRole::ROLE_OUTLINEITEM, eNameOkFromChildren, eNoValue, kNoReqStates,
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
{&nsAccessibilityAtoms::aria_selected, kBoolState, nsIAccessibleStates::STATE_SELECTED | nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_selected, "false", nsIAccessibleStates::STATE_SELECTABLE},
{&nsAccessibilityAtoms::aria_expanded, kBoolState, nsIAccessibleStates::STATE_EXPANDED},
@ -232,6 +205,7 @@ nsStateMapEntry nsARIAMap::gWAIUnivStateMap[] = {
{&nsAccessibilityAtoms::aria_haspopup, kBoolState, nsIAccessibleStates::STATE_HASPOPUP},
{&nsAccessibilityAtoms::aria_busy, "true", nsIAccessibleStates::STATE_BUSY},
{&nsAccessibilityAtoms::aria_busy, "error", nsIAccessibleStates::STATE_INVALID},
{&nsAccessibilityAtoms::aria_disabled, kBoolState, nsIAccessibleStates::STATE_UNAVAILABLE},
kEndEntry
};

View File

@ -95,6 +95,9 @@ nsApplicationAccessibleWrap *nsAccessNode::gApplicationAccessible = nsnull;
nsIAccessibilityService *nsAccessNode::sAccService = nsnull;
nsIAccessibilityService *nsAccessNode::GetAccService()
{
if (!gIsAccessibilityActive)
return nsnull;
if (!sAccService) {
nsresult rv = CallGetService("@mozilla.org/accessibilityService;1",
&sAccService);
@ -222,8 +225,10 @@ NS_IMETHODIMP nsAccessNode::GetUniqueID(void **aUniqueID)
NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **aWindow)
{
*aWindow = nsnull;
nsCOMPtr<nsIAccessibleDocument> docAccessible(GetDocAccessible());
NS_ASSERTION(docAccessible, "No root accessible pointer back, Init() not called.");
if (!docAccessible)
return NS_ERROR_FAILURE; // This node or doc accessible is shut down
return docAccessible->GetWindowHandle(aWindow);
}
@ -315,7 +320,7 @@ void nsAccessNode::ShutdownXPAccessibility()
NS_IF_RELEASE(sAccService);
nsApplicationAccessibleWrap::Unload();
ClearCache(gGlobalDocAccessibleCache);
gGlobalDocAccessibleCache.Enumerate(ClearDocCacheEntry, nsnull);
// Release gApplicationAccessible after everything else is shutdown
// so we don't accidently create it again while tearing down root accessibles
@ -791,6 +796,14 @@ PLDHashOperator nsAccessNode::ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAcce
return PL_DHASH_REMOVE;
}
PLDHashOperator nsAccessNode::ClearDocCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg)
{
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(aAccessNode));
privateAccessNode->Shutdown();
return PL_DHASH_NEXT; // nsDocAccessible::Shutdown() removes the doc from doc cache
}
void
nsAccessNode::ClearCache(nsAccessNodeHashtable& aCache)
{

View File

@ -98,6 +98,7 @@ class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
static void ClearCache(nsAccessNodeHashtable& aCache);
static PLDHashOperator PR_CALLBACK ClearCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg);
static PLDHashOperator PR_CALLBACK ClearDocCacheEntry(const void* aKey, nsCOMPtr<nsIAccessNode>& aAccessNode, void* aUserArg);
// Static cache methods for global document cache
static already_AddRefed<nsIAccessibleDocument> GetDocAccessibleFor(nsIDocument *aDocument);

View File

@ -41,6 +41,7 @@
#include "nsAccessibilityService.h"
#include "nsAccessibilityUtils.h"
#include "nsARIAMap.h"
#include "nsIContentViewer.h"
#include "nsCURILoader.h"
#include "nsDocAccessible.h"
#include "nsHTMLImageAccessibleWrap.h"
@ -155,10 +156,21 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
}
nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
if (progress) {
if (progress)
progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
}
nsAccessNodeWrap::ShutdownAccessibility();
// Cancel and release load timers
while (mLoadTimers.Count() > 0 ) {
nsCOMPtr<nsITimer> timer = mLoadTimers.ObjectAt(0);
void *closure = nsnull;
timer->GetClosure(&closure);
if (closure) {
nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(closure);
NS_RELEASE(webProgress); // Release nsIWebProgress for timer
}
timer->Cancel();
mLoadTimers.RemoveObjectAt(0);
}
}
return NS_OK;
}
@ -169,70 +181,94 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress
{
NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
if (0 == (aStateFlags & (STATE_START | STATE_STOP))) {
if (!aWebProgress || 0 == (aStateFlags & (STATE_START | STATE_STOP))) {
return NS_OK;
}
nsCAutoString name;
aRequest->GetName(name);
if (name.EqualsLiteral("about:blank"))
return NS_OK;
if (NS_FAILED(aStatus) && (aStateFlags & STATE_START))
return NS_OK;
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1");
if (!timer)
return NS_OK;
mLoadTimers.AppendObject(timer);
NS_ADDREF(aWebProgress);
if (aStateFlags & STATE_START)
timer->InitWithFuncCallback(StartLoadCallback, aWebProgress, 0,
nsITimer::TYPE_ONE_SHOT);
else if (NS_SUCCEEDED(aStatus))
timer->InitWithFuncCallback(EndLoadCallback, aWebProgress, 0,
nsITimer::TYPE_ONE_SHOT);
else // Failed end load
timer->InitWithFuncCallback(FailedLoadCallback, aWebProgress, 0,
nsITimer::TYPE_ONE_SHOT);
return NS_OK;
}
NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void *aClosure, PRUint32 aEventType)
{
nsCOMPtr<nsIDOMWindow> domWindow;
aWebProgress->GetDOMWindow(getter_AddRefs(domWindow));
NS_ASSERTION(domWindow, "DOM Window for state change is null");
NS_ENSURE_TRUE(domWindow, NS_ERROR_FAILURE);
nsIWebProgress *webProgress = static_cast<nsIWebProgress*>(aClosure);
webProgress->GetDOMWindow(getter_AddRefs(domWindow));
NS_RELEASE(webProgress);
mLoadTimers.RemoveObject(aTimer);
NS_ENSURE_STATE(domWindow);
nsCOMPtr<nsIDOMDocument> domDoc;
domWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMNode> domDocNode(do_QueryInterface(domDoc));
NS_ENSURE_TRUE(domDocNode, NS_ERROR_FAILURE);
nsCOMPtr<nsIAccessibleDocument> docAccessible;
PRUint32 eventType = 0;
if (aStateFlags & STATE_STOP) {
// Do not create accessible for page load end events
// in case it was already shut down before page finished loading
docAccessible = nsAccessNode::GetDocAccessibleFor(domDocNode); // Cached doc accessibles only
if (!docAccessible)
return NS_OK;
nsCOMPtr<nsIDOMDocument> domDocTest;
docAccessible->GetDocument(getter_AddRefs(domDocTest));
if (domDocTest != domDoc) {
// Doc from accessible is not the doc we started from
// We must be shutdown, and domDocTest should be null
NS_ASSERTION(!domDocTest, "Doc not shut down but reports incorrect DOM document");
return NS_OK;
}
eventType = NS_FAILED(aStatus) ? nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED :
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE;
}
else {
// Get the accessible for the new document.
// If it not created yet this will create it & cache it, as well as
// set up event listeners so that MSAA/ATK toolkit and internal
// accessibility events will get fired.
nsCOMPtr<nsIAccessible> accessible;
GetAccessibleFor(domDocNode, getter_AddRefs(accessible)); // Create if necessary
docAccessible = do_QueryInterface(accessible);
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START;
if (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START) {
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(domWindow));
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(webNav));
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
NS_ENSURE_STATE(docShell);
PRUint32 loadType;
docShell->GetLoadType(&loadType);
if (loadType == LOAD_RELOAD_NORMAL ||
loadType == LOAD_RELOAD_BYPASS_CACHE ||
loadType == LOAD_RELOAD_BYPASS_PROXY ||
loadType == LOAD_RELOAD_BYPASS_PROXY_AND_CACHE) {
eventType = nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD;
aEventType = nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD;
}
}
nsCOMPtr<nsPIAccessibleDocument> privDocAccessible = do_QueryInterface(docAccessible);
if (eventType && privDocAccessible) {
privDocAccessible->FireDocLoadEvents(eventType);
}
nsCOMPtr<nsIDOMDocument> domDoc;
domWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDOMNode> docNode = do_QueryInterface(domDoc);
NS_ENSURE_STATE(docNode);
nsCOMPtr<nsIAccessible> accessible;
GetAccessibleFor(docNode, getter_AddRefs(accessible));
nsCOMPtr<nsPIAccessibleDocument> privDocAccessible = do_QueryInterface(accessible);
NS_ENSURE_STATE(privDocAccessible);
privDocAccessible->FireDocLoadEvents(aEventType);
return NS_OK;
}
void nsAccessibilityService::StartLoadCallback(nsITimer *aTimer, void *aClosure)
{
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
if (accService)
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
}
void nsAccessibilityService::EndLoadCallback(nsITimer *aTimer, void *aClosure)
{
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
if (accService)
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
}
void nsAccessibilityService::FailedLoadCallback(nsITimer *aTimer, void *aClosure)
{
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
if (accService)
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
}
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
NS_IMETHODIMP nsAccessibilityService::OnProgressChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest, PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
@ -378,6 +414,25 @@ nsAccessibilityService::CreateRootAccessible(nsIPresShell *aShell,
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
nsCOMPtr<nsIContentViewer> contentViewer;
docShell->GetContentViewer(getter_AddRefs(contentViewer));
NS_ENSURE_TRUE(contentViewer, NS_ERROR_FAILURE); // Doc was already shut down
PRUint32 busyFlags;
docShell->GetBusyFlags(&busyFlags);
if (busyFlags != nsIDocShell::BUSY_FLAGS_NONE) {
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(docShell));
nsCOMPtr<nsIURI> uri;
webNav->GetCurrentURI(getter_AddRefs(uri));
NS_ENSURE_STATE(uri);
nsCAutoString url;
uri->GetSpec(url);
if (url.EqualsLiteral("about:blank")) {
return NS_OK; // No load events for a busy about:blank -- they are often temporary
}
}
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
do_QueryInterface(container);
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE);

View File

@ -40,7 +40,10 @@
#define __nsAccessibilityService_h__
#include "nsIAccessibilityService.h"
#include "nsCOMArray.h"
#include "nsIObserver.h"
#include "nsITimer.h"
#include "nsIWebProgress.h"
#include "nsIWebProgressListener.h"
#include "nsWeakReference.h"
@ -135,6 +138,11 @@ private:
* @return PR_TRUE if there is a universal ARIA property set on the node
*/
PRBool HasUniversalAriaProperty(nsIContent *aContent, nsIWeakReference *aWeakShell);
static void StartLoadCallback(nsITimer *aTimer, void *aClosure);
static void EndLoadCallback(nsITimer *aTimer, void *aClosure);
static void FailedLoadCallback(nsITimer *aTimer, void *aClosure);
nsCOMArray<nsITimer> mLoadTimers;
};
/**

View File

@ -78,11 +78,14 @@ void nsCaretAccessible::Shutdown()
nsresult nsCaretAccessible::ClearControlSelectionListener()
{
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryReferent(mCurrentControlSelection));
NS_ENSURE_TRUE(selPrivate, NS_ERROR_FAILURE);
mCurrentControlSelection = nsnull;
mCurrentControl = nsnull;
mCurrentControlSelection = nsnull;
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryReferent(mCurrentControlSelection));
if (!selPrivate) {
return NS_OK;
}
return selPrivate->RemoveSelectionListener(this);
}

View File

@ -85,7 +85,7 @@ nsIAtom *nsDocAccessible::gLastFocusedFrameType = nsnull;
//-----------------------------------------------------
nsDocAccessible::nsDocAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell):
nsHyperTextAccessibleWrap(aDOMNode, aShell), mWnd(nsnull),
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE)
mScrollPositionChangedTicks(0), mIsContentLoaded(PR_FALSE), mIsLoadCompleteFired(PR_FALSE)
{
// For GTK+ native window, we do nothing here.
if (!mDOMNode)
@ -526,17 +526,13 @@ NS_IMETHODIMP nsDocAccessible::Shutdown()
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
ShutdownChildDocuments(treeItem);
if (mDocLoadTimer) {
mDocLoadTimer->Cancel();
mDocLoadTimer = nsnull;
}
RemoveEventListeners();
mWeakShell = nsnull; // Avoid reentrancy
ClearCache(mAccessNodeCache);
nsCOMPtr<nsIDocument> kungFuDeathGripDoc = mDocument;
mDocument = nsnull;
nsHyperTextAccessibleWrap::Shutdown();
@ -553,6 +549,10 @@ NS_IMETHODIMP nsDocAccessible::Shutdown()
}
}
// Remove from the cache after other parts of Shutdown(), so that Shutdown() procedures
// can find the doc or root accessible in the cache if they need it.
gGlobalDocAccessibleCache.Remove(static_cast<void*>(kungFuDeathGripDoc));
return NS_OK;
}
@ -766,10 +766,20 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
(aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
if (mIsContentLoaded == isFinished) {
mIsContentLoaded = isFinished;
if (isFinished) {
if (mIsLoadCompleteFired)
return NS_OK;
mIsLoadCompleteFired = PR_TRUE;
}
nsCOMPtr<nsIDocShellTreeItem> treeItem =
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
if (!treeItem) {
return NS_OK;
}
mIsContentLoaded = isFinished;
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
if (isFinished) {
// Need to wait until scrollable view is available
@ -780,36 +790,31 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
// Make the parent forget about the old document as a child
privateAccessible->InvalidateChildren();
}
// Use short timer before firing state change event for finished doc,
// because the window is made visible asynchronously
if (!mDocLoadTimer) {
mDocLoadTimer = do_CreateInstance("@mozilla.org/timer;1");
}
if (mDocLoadTimer) {
mDocLoadTimer->InitWithFuncCallback(DocLoadCallback, this, 0,
nsITimer::TYPE_ONE_SHOT);
}
} else {
nsCOMPtr<nsIDocShellTreeItem> treeItem =
nsAccUtils::GetDocShellTreeItemFor(mDOMNode);
if (!treeItem) {
return NS_OK;
}
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
if (sameTypeRoot != treeItem) {
return NS_OK;
// Fire show/hide events to indicate frame/iframe content is new, rather than
// doc load event which causes screen readers to act is if entire page is reloaded
InvalidateCacheSubtree(nsnull, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
}
// Fire STATE_CHANGE event for doc load finish if focus is in same doc tree
if (gLastFocusedNode) {
nsCOMPtr<nsIDocShellTreeItem> focusedTreeItem =
nsAccUtils::GetDocShellTreeItemFor(gLastFocusedNode);
if (focusedTreeItem) {
nsCOMPtr<nsIDocShellTreeItem> sameTypeRootOfFocus;
focusedTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRootOfFocus));
if (sameTypeRoot == sameTypeRootOfFocus) {
nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_BUSY, PR_FALSE, PR_FALSE);
FireAccessibleEvent(accEvent);
FireAnchorJumpEvent();
}
}
}
// Loading document: fire EVENT_STATE_CHANGE to set STATE_BUSY
nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
new nsAccStateChangeEvent(this, nsIAccessibleStates::STATE_BUSY,
PR_FALSE, PR_TRUE);
FireAccessibleEvent(accEvent);
}
nsAccUtils::FireAccEvent(aEventType, this);
if (sameTypeRoot == treeItem) {
// Not a frame or iframe
nsAccUtils::FireAccEvent(aEventType, this);
}
return NS_OK;
}
@ -2067,55 +2072,3 @@ nsDocAccessible::FireShowHideEvents(nsIDOMNode *aDOMNode, PRBool aAvoidOnThisNod
return NS_OK;
}
void nsDocAccessible::DocLoadCallback(nsITimer *aTimer, void *aClosure)
{
// Doc has finished loading, fire "load finished" event
// By using short timer we can wait make the window visible,
// which it does asynchronously. This avoids confusing the screen reader with a
// hidden window. Waiting also allows us to see of the document has focus,
// which is important because we only fire doc loaded events for focused documents.
nsDocAccessible *docAcc =
reinterpret_cast<nsDocAccessible*>(aClosure);
if (!docAcc) {
return;
}
// Fire doc finished event
nsCOMPtr<nsIDOMNode> docDomNode;
docAcc->GetDOMNode(getter_AddRefs(docDomNode));
nsCOMPtr<nsIDocument> doc(do_QueryInterface(docDomNode));
if (doc) {
nsCOMPtr<nsISupports> container = doc->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = do_QueryInterface(container);
if (!docShellTreeItem) {
return;
}
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
if (sameTypeRoot != docShellTreeItem) {
// A frame or iframe has finished loading new content
docAcc->InvalidateCacheSubtree(nsnull, nsIAccessibleEvent::EVENT_DOM_SIGNIFICANT_CHANGE);
return;
}
// Fire STATE_CHANGE event for doc load finish if focus is in same doc tree
if (gLastFocusedNode) {
nsCOMPtr<nsIDocShellTreeItem> focusedTreeItem =
nsAccUtils::GetDocShellTreeItemFor(gLastFocusedNode);
if (focusedTreeItem) {
nsCOMPtr<nsIDocShellTreeItem> sameTypeRootOfFocus;
focusedTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRootOfFocus));
if (sameTypeRoot == sameTypeRootOfFocus) {
nsCOMPtr<nsIAccessibleStateChangeEvent> accEvent =
new nsAccStateChangeEvent(docAcc, nsIAccessibleStates::STATE_BUSY,
PR_FALSE, PR_FALSE);
docAcc->FireAccessibleEvent(accEvent);
docAcc->FireAnchorJumpEvent();
}
}
}
}
}

View File

@ -214,6 +214,7 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
nsCOMPtr<nsITimer> mFireEventTimer;
PRUint16 mScrollPositionChangedTicks; // Used for tracking scroll events
PRPackedBool mIsContentLoaded;
PRPackedBool mIsLoadCompleteFired;
nsCOMArray<nsIAccessibleEvent> mEventsToFire;
protected:
@ -221,10 +222,6 @@ protected:
PRBool mIsAnchorJumped;
static PRUint32 gLastFocusedAccessiblesState;
static nsIAtom *gLastFocusedFrameType;
private:
static void DocLoadCallback(nsITimer *aTimer, void *aClosure);
nsCOMPtr<nsITimer> mDocLoadTimer;
};
#endif

View File

@ -406,29 +406,11 @@ void nsRootAccessible::TryFireEarlyLoadEvent(nsIDOMNode *aDocNode)
nsCOMPtr<nsIDocShellTreeItem> rootContentTreeItem;
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(rootContentTreeItem));
NS_ASSERTION(rootContentTreeItem, "No root content tree item");
if (!rootContentTreeItem) { // Not at root of content
return;
if (rootContentTreeItem == treeItem) {
// No frames or iframes, so we can fire the doc load finished event early
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD, aDocNode,
eRemoveDupes);
}
if (rootContentTreeItem != treeItem) {
nsCOMPtr<nsIAccessibleDocument> rootContentDocAccessible =
GetDocAccessibleFor(rootContentTreeItem);
nsCOMPtr<nsIAccessible> rootContentAccessible =
do_QueryInterface(rootContentDocAccessible);
if (!rootContentAccessible) {
return;
}
PRUint32 state, extState;
rootContentAccessible->GetFinalState(&state, &extState);
if ((state & nsIAccessibleStates::STATE_BUSY) ||
(extState & nsIAccessibleStates::EXT_STATE_DEFUNCT)) {
// Don't fire page load events on subdocuments for initial page load of entire page
return;
}
}
// No frames or iframes, so we can fire the doc load finished event early
FireDelayedToolkitEvent(nsIAccessibleEvent::EVENT_INTERNAL_LOAD, aDocNode,
eRemoveDupes);
}
PRBool nsRootAccessible::FireAccessibleFocusEvent(nsIAccessible *aAccessible,
@ -632,9 +614,6 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
nsCOMPtr<nsPIAccessNode> privateAcc = do_QueryInterface(accDoc);
if (privateAcc) {
privateAcc->Shutdown();
// Remove from the cache after Shutdown(), so that Shutdown() procedures
// can find the doc or root accessible in the cache if they need it.
gGlobalDocAccessibleCache.Remove(static_cast<void*>(doc));
}
return NS_OK;
}

View File

@ -121,17 +121,17 @@ __try {
nsCOMPtr<nsIURI> uri;
nsresult rv = acc->GetURI(aIndex, getter_AddRefs(uri));
if (NS_SUCCEEDED(rv))
if (NS_FAILED(rv) || !uri)
return E_FAIL;
nsCAutoString prePath;
rv = uri->GetPrePath(prePath);
if (NS_SUCCEEDED(rv))
if (NS_FAILED(rv))
return E_FAIL;
nsCAutoString path;
rv = uri->GetPath(path);
if (NS_SUCCEEDED(rv))
if (NS_FAILED(rv))
return E_FAIL;
nsAutoString stringURI;

View File

@ -1394,6 +1394,9 @@ STDMETHODIMP
nsAccessibleWrap::get_windowHandle(HWND *windowHandle)
{
__try {
*windowHandle = 0;
if (!mDOMNode)
return E_FAIL;
void *handle = nsnull;
nsresult rv = GetOwnerWindow(&handle);
if (NS_FAILED(rv))

View File

@ -162,11 +162,6 @@ __try {
return E_FAIL;
}
NS_IMETHODIMP nsDocAccessibleWrap::Shutdown()
{
return nsDocAccessible::Shutdown();
}
NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
{
// Staying on the same page, jumping to a named anchor

View File

@ -87,7 +87,6 @@ public:
/* [in] */ VARIANT varChild,
/* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispChild);
NS_IMETHOD Shutdown();
NS_IMETHOD FireAnchorJumpEvent();
};

View File

@ -48,6 +48,9 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\
test_bug368835.xul \
test_groupattrs.xul \
test_nsIAccessibleTable_1.html \
test_nsIAccessibleTable_2.html \
test_nsIAccessibleTable_3.html \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -167,7 +167,7 @@
function doTest()
{
// Check whether accessbility support is enabled.
// Check whether accessibility support is enabled.
if (!("@mozilla.org/accessibleRetrieval;1" in Components.classes)) {
SimpleTest.finish();
return;

View File

@ -0,0 +1,144 @@
<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript">
function doTest()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var table = document.getElementById("table");
var accService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
var accTable = accService.getAccessibleFor(table).
QueryInterface(Components.interfaces.nsIAccessibleTable);
var caption = accTable.caption;
is(caption.firstChild.name, "Test Table", "wrong text inside caption");
const nsIAccessNode = Components.interfaces.nsIAccessible;
is(caption.children.queryElementAt(0, nsIAccessNode).name, "Test Table",
"wrong text inside caption");
is(accTable.summary, "this is a test table for nsIAccessibleTable",
"wrong summary on table");
is(accTable.columns, 4,"wrong number of columns");
is(accTable.rows, 3, "wrong number of rows");
var s = window.getSelection();
if (s.rangeCount > 0)
s.removeAllRanges();
var cell = document.getElementById("col2b");
var range = document.createRange();
range.selectNode(cell);
s.addRange(range);
is(accTable.selectedCellsCount, 1,"only one cell selected");
cell = document.getElementById("col2a");
range.selectNode(cell);
s.addRange(range);
cell = document.getElementById("col2c");
range.selectNode(cell);
s.addRange(range);
is(accTable.selectedColumnsCount, 1, "only one column selected");
cell = document.getElementById("row2a");
range.selectNode(cell);
s.addRange(range);
cell = document.getElementById("row2b");
range.selectNode(cell);
s.addRange(range);
cell = document.getElementById("row2c");
range.selectNode(cell);
s.addRange(range);
is(accTable.selectedRowsCount, 1, "no cells selected");
var rowheader;
var works;
works = true;
try {
rowheader = accTable.rowHeader;
}
catch (e) {
works = false;
}
todo(works, "rowHeader should not throw");
var columnHeader;
works = true;
try {
columnHeader = accTable.columnHeader;
columnHeaderIndex =columnHeader.getIndexAt(0,2);
is(columnHeaderIndex, 2, "columnheaderindex is wrong");
}
catch (e) {
works = false;
}
todo(works, "columnHeader should not throw");
var columnDescription;
works = true;
try{
columnDescription = accTable.getColumnDescription(1);
}
catch (e) {
works = false;
}
todo(works, "columnDescription should not throw");
var rowDescription;
works = true;
try {
rowDescription = accTable.getRowDescription(1);
}
catch (e) {
works = false;
}
todo(works, "rowDescription should not throw");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body >
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<!-- Test Table -->
<br><br><b> Testing Table:</b><br><br>
<center>
<table id="table" border="1"
summary="this is a test table for nsIAccessibleTable" >
<caption>Test Table</caption>
<thead>
<tr>
<th></th>
<th>columnHeader_1</th>
<th id ="col2a">columnHeader_2</th>
<th>columnHeader_3</th>
</tr>
</thead>
<tr>
<th id="row2a">rowHeader_1</th>
<td id="row2b">row1_column1</td>
<td id ="col2b">row1_column2</td>
<td id="row2c">row1_column3</td>
</tr>
<tr>
<th>rowHeader_2</th>
<td>row2_column1</td>
<td id ="col2c">row2_column2</td>
<td>row2_column3</td>
</tr>
</table>
</center>
</body>
</html>

View File

@ -0,0 +1,87 @@
<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> nsIAccessibleTable Interface Test Case </title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript">
function doTest()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var table = document.getElementById("table");
var accService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
var accTable = accService.getAccessibleFor(table).
QueryInterface(Components.interfaces.nsIAccessibleTable);
is(accTable.getIndexAt(2,4), 17, "wrong index returned");
is(accTable.getColumnAtIndex(18), 5,"got wrong column");
is(accTable.getRowAtIndex(10), 1, "wrong row");
is(accTable.getColumnExtentAt(2,2), 2, "colspan wrong");
is(accTable.getColumnExtentAt(0,3), 2, "colspan wrong");
is(accTable.getColumnExtentAt(3,5), 1, "colspan");
is(accTable.getRowExtentAt(0,7), 4, "rowspan wrong");
is(accTable.getRowExtentAt(2,7), 4,"rowspan wrong");
is(accTable.getColumnExtentAt(2,3), 1, "colspan wrong");
is(accTable.cellRefAt(2,1).firstChild.name, "c1", "wrong cell");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<!-- Test Table -->
<br><br><b> Testing Table:</b><br><br>
<center>
<table cellpadding="2" cellspacing="2" border="1" width="50%" id="table">
<tbody>
<tr>
<td><br></td>
<td><br></td>
<td rowspan="1" colspan="2"><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td rowspan="4" colspan="1"><br></td>
</tr>
<tr>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
</tr>
<tr>
<td><br></td>
<td rowspan="2" colspan="2">c1</td>
<td><br></td>
<td><br></td>
<td rowspan="2" colspan="1"><br></td>
<td><br></td>
</tr>
<tr>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
</tr>
</tbody>
</table>
</center>
</body>
</html>

View File

@ -0,0 +1,127 @@
<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> nsIAccessibleTable Interface Test Case </title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript">
function doTest()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var table = document.getElementById("table");
var accService = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
var accTable = accService.getAccessibleFor(table).
QueryInterface(Components.interfaces.nsIAccessibleTable);
is(accTable.getSelectedCells({}).length, 0, "no cell selected");
for (var i = 0; i < 4; i++) {
accTable.selectRow(i);
for (var j = 0; j < 4; j++) {
if (i == j) {
ok(accTable.isRowSelected(i),"row not selected");
}
else {
todo(!accTable.isRowSelected(i),"row selected");
}
}
}
todo_is(accTable.selectedRowsCount, 1, "only one row should be selected");
todo_is(accTable.getSelectedRows({}).length, 1,
"only one row should be selected");
for (var i = 0; i < 4; i++) {
accTable.unselectRow(i);
ok(!accTable.isRowSelected(i), "row still selected");
}
todo_is(accTable.getSelectedCells({}).length, 0, "no cell selected");
todo_is(accTable.selectedCellsCount, 0, "no cell selected");
var s = window.getSelection();
if (s.rangeCount > 0)
s.removeAllRanges();
is(accTable.getSelectedCells({}).length, 0, "no cell selected");
is(accTable.selectedCellsCount, 0, "no cell selected");
for (var i = 0; i < 8; i++) {
accTable.selectColumn(i);
for (var j = 0; j < 8; j++) {
if (i ==j) {
ok(accTable.isColumnSelected(i),"column not selected");
}
else {
todo(!accTable.isColumnSelected(i),"column is selected");
}
}
}
todo_is(accTable.selectedColumnsCount, 1,
"only one column should be selected");
todo_is(accTable.getSelectedColumns({}).length, 1,
"only one column should be selected");
for (var i = 0; i < 8; i++) {
accTable.unselectColumn(i);
ok(!accTable.isColumnSelected(i),"column still selected");
}
is(accTable.selectedColumnsCount, 0, "no column should be selected");
ok(!accTable.isProbablyForLayout(), "table is not for layout");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=410052">Mozilla Bug 410052</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<!-- Test Table -->
<br><br><b> Testing Table:</b><br><br>
<center>
<table cellpadding="2" cellspacing="2" border="1" width="50%" id="table">
<tbody>
<tr>
<td><br></td>
<td><br></td>
<td rowspan="1" colspan="2"><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td rowspan="4" colspan="1"><br></td>
</tr>
<tr>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
</tr>
<tr>
<td><br></td>
<td rowspan="2" colspan="2">c1</td>
<td><br></td>
<td><br></td>
<td rowspan="2" colspan="1"><br></td>
<td><br></td>
</tr>
<tr>
<td><br></td>
<td><br></td>
<td><br></td>
<td><br></td>
</tr>
</tbody>
</table>
</center>
</body>
</html>

View File

@ -197,6 +197,7 @@ pref("browser.chrome.site_icons", true);
pref("browser.chrome.favicons", true);
pref("browser.formfill.enable", true);
pref("browser.warnOnQuit", true);
pref("browser.warnOnRestart", true);
#ifdef UNIX_BUT_NOT_MAC
pref("browser.urlbar.clickSelectsAll", false);
@ -210,6 +211,7 @@ pref("browser.urlbar.doubleClickSelectsAll", false);
#endif
pref("browser.urlbar.autoFill", false);
pref("browser.urlbar.matchOnlyTyped", false);
pref("browser.urlbar.filter.javascript", true);
// the maximum number of results to show in autocomplete when doing richResults
pref("browser.urlbar.maxRichResults", 25);
@ -364,7 +366,7 @@ pref("privacy.sanitize.promptOnSanitize", true);
pref("network.proxy.share_proxy_settings", false); // use the same proxy settings for all protocols
pref("network.cookie.cookieBehavior", 1); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
pref("network.cookie.cookieBehavior", 0); // 0-Accept, 1-dontAcceptForeign, 2-dontUse
// l12n and i18n
pref("intl.accept_languages", "chrome://global/locale/intl.properties");
@ -571,16 +573,16 @@ pref("browser.safebrowsing.enabled", true);
pref("browser.safebrowsing.malware.enabled", true);
// Non-enhanced mode (local url lists) URL list to check for updates
pref("browser.safebrowsing.provider.0.updateURL", "http://sb.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.1");
pref("browser.safebrowsing.provider.0.updateURL", "http://safebrowsing.clients.google.com/safebrowsing/downloads?client={moz:client}&appver={moz:version}&pver=2.1");
pref("browser.safebrowsing.dataProvider", 0);
// Does the provider name need to be localizable?
pref("browser.safebrowsing.provider.0.name", "Google");
pref("browser.safebrowsing.provider.0.lookupURL", "http://sb.google.com/safebrowsing/lookup?sourceid=firefox-antiphish&features=TrustRank&client={moz:client}&appver={moz:version}&");
pref("browser.safebrowsing.provider.0.keyURL", "https://sb-ssl.google.com/safebrowsing/getkey?client={moz:client}&");
pref("browser.safebrowsing.provider.0.reportURL", "http://sb.google.com/safebrowsing/report?");
pref("browser.safebrowsing.provider.0.gethashURL", "http://sb.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.1");
pref("browser.safebrowsing.provider.0.lookupURL", "http://safebrowsing.clients.google.com/safebrowsing/lookup?sourceid=firefox-antiphish&features=TrustRank&client={moz:client}&appver={moz:version}&");
pref("browser.safebrowsing.provider.0.keyURL", "https://sb-ssl.google.com/safebrowsing/newkey?client={moz:client}&appver={moz:version}&pver=2.1");
pref("browser.safebrowsing.provider.0.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/report?");
pref("browser.safebrowsing.provider.0.gethashURL", "http://safebrowsing.clients.google.com/safebrowsing/gethash?client={moz:client}&appver={moz:version}&pver=2.1");
// privacy policy -- Both url and fallbackurl must exist, although they may
// point to the same file. fallbackurl must be a chrome url
@ -598,6 +600,9 @@ pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%L
// Name of the about: page contributed by safebrowsing to handle display of error
// pages on phishing/malware hits. (bug 399233)
pref("urlclassifier.alternate_error_page", "blocked");
// The number of random entries to send with a gethash request.
pref("urlclassifier.gethashnoise", 4);
#endif
// defaults to true
@ -609,7 +614,7 @@ pref("browser.EULA.version", 2);
pref("browser.sessionstore.enabled", true);
pref("browser.sessionstore.resume_from_crash", true);
pref("browser.sessionstore.resume_session_once", false);
// minimal interval between two save operations in milliseconds
pref("browser.sessionstore.interval", 10000);
// maximum amount of POSTDATA to be saved in bytes per history entry (-1 = all of it)
@ -637,6 +642,10 @@ pref("browser.places.createdSmartBookmarks", false);
// XXX to be removed after beta 2 (bug 391419)
pref("browser.places.migratePostDataAnnotations", true);
// If true, will update the Smart Bookmarks uri for
// recent tags (bug 385245). Useful just for FX3 beta users.
pref("browser.places.updateRecentTagsUri", true);
// the (maximum) number of the recent visits to sample
// when calculating frecency
pref("places.frecency.numVisits", 10);
@ -699,6 +708,9 @@ pref("browser.offline-apps.notify", true);
// if true, use full page zoom instead of text zoom
pref("browser.zoom.full", true);
// Whether or not to save and restore zoom levels on a per-site basis.
pref("browser.zoom.siteSpecific", true);
// replace newlines with spaces when pasting into <input type="text"> fields
pref("editor.singleLine.pasteNewlines", 2);

View File

@ -184,36 +184,45 @@
<menuseparator id="frame-sep"/>
<menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
<menupopup>
<menuitem label="&showOnlyThisFrameCmd.label;"
<menuitem id="context-showonlythisframe"
label="&showOnlyThisFrameCmd.label;"
accesskey="&showOnlyThisFrameCmd.accesskey;"
oncommand="gContextMenu.showOnlyThisFrame();"/>
<menuitem label="&openFrameCmd.label;"
<menuitem id="context-openframe"
label="&openFrameCmd.label;"
accesskey="&openFrameCmd.accesskey;"
oncommand="gContextMenu.openFrame();"/>
<menuitem label="&openFrameCmdInTab.label;"
<menuitem id="context-openframeintab"
label="&openFrameCmdInTab.label;"
accesskey="&openFrameCmdInTab.accesskey;"
oncommand="gContextMenu.openFrameInTab();"/>
<menuseparator/>
<menuitem label="&reloadFrameCmd.label;"
<menuitem id="context-reloadframe"
label="&reloadFrameCmd.label;"
accesskey="&reloadFrameCmd.accesskey;"
oncommand="gContextMenu.reloadFrame();"/>
<menuseparator/>
<menuitem label="&bookmarkThisFrameCmd.label;"
<menuitem id="context-bookmarkframe"
label="&bookmarkThisFrameCmd.label;"
accesskey="&bookmarkThisFrameCmd.accesskey;"
oncommand="gContextMenu.addBookmarkForFrame();"/>
<menuitem label="&saveFrameCmd.label;"
<menuitem id="context-saveframe"
label="&saveFrameCmd.label;"
accesskey="&saveFrameCmd.accesskey;"
oncommand="saveDocument(gContextMenu.target.ownerDocument);"/>
<menuseparator/>
<menuitem label="&printFrameCmd.label;"
<menuitem id="context-printframe"
label="&printFrameCmd.label;"
accesskey="&printFrameCmd.accesskey;"
oncommand="gContextMenu.printFrame();"/>
<menuseparator/>
<menuitem label="&viewFrameSourceCmd.label;"
<menuitem id="context-viewframesource"
label="&viewFrameSourceCmd.label;"
accesskey="&viewFrameSourceCmd.accesskey;"
oncommand="gContextMenu.viewFrameSource();"
observes="isFrameImage"/>
<menuitem label="&viewFrameInfoCmd.label;"
<menuitem id="context-viewframeinfo"
label="&viewFrameInfoCmd.label;"
accesskey="&viewFrameInfoCmd.accesskey;"
oncommand="gContextMenu.viewFrameInfo();"/>
</menupopup>

View File

@ -582,12 +582,12 @@ var BookmarksEventHandler = {
var target = aEvent.originalTarget;
var view = PlacesUtils.getViewForNode(target);
if (PlacesUtils.nodeIsFolder(view.selectedNode)) {
if (target.node && PlacesUtils.nodeIsFolder(target.node)) {
// Don't open the root folder in tabs when the empty area on the toolbar
// is middle-clicked or when a non-bookmark item except for Open in Tabs)
// in a bookmarks menupopup is middle-clicked.
if (!view.controller.rootNodeIsSelected())
view.controller.openSelectionInTabs(aEvent);
if (target.localName == "menu" || target.localName == "toolbarbutton")
PlacesUtils.openContainerNodeInTabs(target.node, aEvent);
}
else
this.onCommand(aEvent);
@ -624,11 +624,8 @@ var BookmarksEventHandler = {
*/
onCommand: function BM_onCommand(aEvent) {
var target = aEvent.originalTarget;
if (target.node) {
PlacesUtils.getViewForNode(target)
.controller
.openSelectedNodeWithEvent(aEvent);
}
if (target.node)
PlacesUtils.openNodeWithEvent(target.node, aEvent);
},
/**
@ -1027,7 +1024,7 @@ function placesMigrationTasks() {
// XXX - REMOVE ME FOR BETA 3 (bug 391419)
if (gPrefService.getBoolPref("browser.places.migratePostDataAnnotations")) {
const annosvc = PlacesUtils.annotations;
const bmsvc = PlacesUtils.bookmarks;
var bmsvc = PlacesUtils.bookmarks;
const oldPostDataAnno = "URIProperties/POSTData";
var pages = annosvc.getPagesWithAnnotation(oldPostDataAnno, {});
for (let i = 0; i < pages.length; i++) {
@ -1051,4 +1048,30 @@ function placesMigrationTasks() {
}
gPrefService.setBoolPref("browser.places.migratePostDataAnnotations", false);
}
if (gPrefService.getBoolPref("browser.places.updateRecentTagsUri")) {
var bmsvc = PlacesUtils.bookmarks;
var tagsFolder = bmsvc.tagsFolder;
var oldUriSpec = "place:folder=" + tagsFolder + "&group=3&queryType=1"+
"&applyOptionsToContainers=1&sort=12&maxResults=10";
var maxResults = 10;
var newUriSpec = "place:type=" +
Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
"&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
"&maxResults=" + maxResults;
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var oldUri = ios.newURI(oldUriSpec, null, null);
var newUri = ios.newURI(newUriSpec, null, null);
let bookmarks = bmsvc.getBookmarkIdsForURI( oldUri, {});
for (let i = 0; i < bookmarks.length; i++) {
bmsvc.changeBookmarkURI( bookmarks[i], newUri);
}
gPrefService.setBoolPref("browser.places.updateRecentTagsUri", false);
}
}

View File

@ -192,6 +192,9 @@
# Do *not* tamper with these values without talking to ben@mozilla.org
#
<key id="key_search" key="&searchFocus.commandkey;" command="Tools:Search" modifiers="accel"/>
#ifdef XP_MACOSX
<key id="key_search2" key="&findOnCmd.commandkey;" command="Tools:Search" modifiers="accel,alt"/>
#endif
#ifdef XP_WIN
<key id="key_search2" key="&searchFocus.commandkey2;" command="Tools:Search" modifiers="accel"/>
#endif

View File

@ -79,13 +79,24 @@ var FullZoom = {
getService(Ci.nsIContentPrefService);
},
get _prefBranch FullZoom_get__prefBranch() {
delete this._prefBranch;
return this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch2);
},
// browser.zoom.siteSpecific preference cache
siteSpecific: undefined,
//**************************************************************************//
// nsISupports
// We can't use the Ci shortcut here because it isn't defined yet.
interfaces: [Components.interfaces.nsIDOMEventListener,
Components.interfaces.nsIObserver,
Components.interfaces.nsIContentPrefObserver,
Components.interfaces.nsISupportsWeakReference,
Components.interfaces.nsISupports],
QueryInterface: function FullZoom_QueryInterface(aIID) {
@ -104,9 +115,16 @@ var FullZoom = {
// Register ourselves with the service so we know when our pref changes.
this._cps.addObserver(this.name, this);
// Listen for changes to the browser.zoom.siteSpecific preference so we can
// enable/disable per-site saving and restoring of zoom levels accordingly.
this.siteSpecific =
this._prefBranch.getBoolPref("browser.zoom.siteSpecific");
this._prefBranch.addObserver("browser.zoom.siteSpecific", this, true);
},
destroy: function FullZoom_destroy() {
this._prefBranch.removeObserver("browser.zoom.siteSpecific", this);
this._cps.removeObserver(this.name, this);
window.removeEventListener("DOMMouseScroll", this, false);
delete this._cps;
@ -164,6 +182,21 @@ var FullZoom = {
window.setTimeout(function (self) { self._applySettingToPref() }, 0, this);
},
// nsIObserver
observe: function (aSubject, aTopic, aData) {
switch(aTopic) {
case "nsPref:changed":
switch(aData) {
case "browser.zoom.siteSpecific":
this.siteSpecific =
this._prefBranch.getBoolPref("browser.zoom.siteSpecific");
break;
}
break;
}
},
// nsIContentPrefObserver
onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue) {
@ -257,7 +290,7 @@ var FullZoom = {
* one.
**/
_applyPrefToSetting: function FullZoom__applyPrefToSetting(aValue) {
if (gInPrintPreviewMode)
if (!this.siteSpecific || gInPrintPreviewMode)
return;
try {
@ -272,7 +305,7 @@ var FullZoom = {
},
_applySettingToPref: function FullZoom__applySettingToPref() {
if (gInPrintPreviewMode)
if (!this.siteSpecific || gInPrintPreviewMode)
return;
var zoomLevel = ZoomManager.zoom;

View File

@ -23,6 +23,11 @@ toolbar[printpreview="true"] {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup");
}
#urlbar-throbber:not([busy="true"]),
#urlbar-throbber[busy="true"] + #page-proxy-favicon {
display: none;
}
/* ::::: Unified Back-/Forward Button ::::: */
#back-forward-dropmarker > image ,
#back-forward-dropmarker > label {

View File

@ -75,9 +75,7 @@ var gLastBrowserCharset = null;
var gPrevCharset = null;
var gURLBar = null;
var gFindBar = null;
var gProxyButton = null;
var gProxyFavIcon = null;
var gProxyDeck = null;
var gNavigatorBundle = null;
var gIsLoadingBlank = false;
var gLastValidURLStr = "";
@ -1968,8 +1966,7 @@ function URLBarSetURI(aURI) {
SetPageProxyState(state);
}
// If "ESC" is pressed in the url bar, we replace the urlbar's value with the url of the page
// and highlight it, unless it is empty.
// Replace the urlbar's value with the url of the page.
function handleURLBarRevert() {
var throbberElement = document.getElementById("navigator-throbber");
var isScrolling = gURLBar.popupOpen;
@ -1980,7 +1977,9 @@ function handleURLBarRevert() {
// and user is NOT key-scrolling through autocomplete list
if ((!throbberElement || !throbberElement.hasAttribute("busy")) && !isScrolling) {
URLBarSetURI();
if (gURLBar.value)
// If the value isn't empty and the urlbar has focus, select the value.
if (gURLBar.value && gURLBar.hasAttribute("focused"))
gURLBar.select();
}
@ -2107,6 +2106,28 @@ function UpdateUrlbarSearchSplitterState()
splitter.parentNode.removeChild(splitter);
}
var LocationBarHelpers = {
_timeoutID: null,
_searchBegin: function LocBar_searchBegin() {
function delayedBegin(self) {
self._timeoutID = null;
document.getElementById("urlbar-throbber").setAttribute("busy", "true");
}
this._timeoutID = setTimeout(delayedBegin, 500, this);
},
_searchComplete: function LocBar_searchComplete() {
// Did we finish the search before delayedBegin was invoked?
if (this._timeoutID) {
clearTimeout(this._timeoutID);
this._timeoutID = null;
}
document.getElementById("urlbar-throbber").removeAttribute("busy");
}
};
function UpdatePageProxyState()
{
if (gURLBar && gURLBar.value != gLastValidURLStr)
@ -2118,15 +2139,11 @@ function SetPageProxyState(aState)
if (!gURLBar)
return;
if (!gProxyButton)
gProxyButton = document.getElementById("page-proxy-button");
if (!gProxyFavIcon)
gProxyFavIcon = document.getElementById("page-proxy-favicon");
if (!gProxyDeck)
gProxyDeck = document.getElementById("page-proxy-deck");
gURLBar.setAttribute("pageproxystate", aState);
gProxyButton.setAttribute("pageproxystate", aState);
gProxyFavIcon.setAttribute("pageproxystate", aState);
// the page proxy state is set to valid via OnLocationChange, which
// gets called when we switch tabs.
@ -2150,21 +2167,17 @@ function PageProxySetIcon (aURL)
PageProxyClearIcon();
else if (gProxyFavIcon.getAttribute("src") != aURL)
gProxyFavIcon.setAttribute("src", aURL);
else if (gProxyDeck.selectedIndex != 1)
gProxyDeck.selectedIndex = 1;
}
function PageProxyClearIcon ()
{
if (gProxyDeck.selectedIndex != 0)
gProxyDeck.selectedIndex = 0;
if (gProxyFavIcon.hasAttribute("src"))
gProxyFavIcon.removeAttribute("src");
gProxyFavIcon.removeAttribute("src");
}
function PageProxyDragGesture(aEvent)
{
if (gProxyButton.getAttribute("pageproxystate") == "valid") {
if (gProxyFavIcon.getAttribute("pageproxystate") == "valid") {
nsDragAndDrop.startDrag(aEvent, proxyIconDNDObserver);
return true;
}
@ -2969,12 +2982,12 @@ function FillHistoryMenu(aParent) {
let iconURL = Cc["@mozilla.org/browser/favicon-service;1"]
.getService(Ci.nsIFaviconService)
.getFaviconForPage(entry.URI).spec;
item.setAttribute("image", iconURL);
item.style.listStyleImage = "url(" + iconURL + ")";
} catch (ex) {}
}
if (j < index) {
item.className = "unified-nav-back";
item.className = "unified-nav-back menuitem-iconic";
item.setAttribute("tooltiptext", tooltipBack);
} else if (j == index) {
item.setAttribute("type", "radio");
@ -2982,7 +2995,7 @@ function FillHistoryMenu(aParent) {
item.className = "unified-nav-current";
item.setAttribute("tooltiptext", tooltipCurrent);
} else {
item.className = "unified-nav-forward";
item.className = "unified-nav-forward menuitem-iconic";
item.setAttribute("tooltiptext", tooltipForward);
}
@ -3122,9 +3135,7 @@ function BrowserToolboxCustomizeDone(aToolboxChanged)
// Update global UI elements that may have been added or removed
if (aToolboxChanged) {
gURLBar = document.getElementById("urlbar");
gProxyButton = document.getElementById("page-proxy-button");
gProxyFavIcon = document.getElementById("page-proxy-favicon");
gProxyDeck = document.getElementById("page-proxy-deck");
gHomeButton.updateTooltip();
gIdentityHandler._cacheElements();
window.XULBrowserWindow.init();
@ -3135,6 +3146,14 @@ function BrowserToolboxCustomizeDone(aToolboxChanged)
document.getElementById('Browser:Back').hasAttribute('disabled') &&
document.getElementById('Browser:Forward').hasAttribute('disabled');
// support downgrading to Firefox 2.0
var navBar = document.getElementById("nav-bar");
navBar.setAttribute("currentset",
navBar.getAttribute("currentset")
.replace("unified-back-forward-button",
"unified-back-forward-button,back-button,forward-button"));
document.persist(navBar.id, "currentset");
#ifndef XP_MACOSX
updateEditUIVisibility();
#endif
@ -4980,12 +4999,18 @@ var OfflineApps = {
// OfflineApps Public Methods
init: function ()
{
// XXX: empty init left as a placeholder for patch in bug 397417
var obs = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
obs.addObserver(this, "dom-storage-warn-quota-exceeded", false);
obs.addObserver(this, "offline-cache-update-completed", false);
},
uninit: function ()
{
// XXX: empty uninit left as a placeholder for patch in bug 397417
var obs = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
obs.removeObserver(this, "dom-storage-warn-quota-exceeded");
obs.removeObserver(this, "offline-cache-update-completed");
},
/////////////////////////////////////////////////////////////////////////////
@ -5013,6 +5038,92 @@ var OfflineApps = {
}
},
_getManifestURI: function(aWindow) {
var attr = aWindow.document.documentElement.getAttribute("manifest");
if (!attr) return null;
try {
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var contentURI = ios.newURI(aWindow.location.href, null, null);
return ios.newURI(attr, aWindow.document.characterSet, contentURI);
} catch (e) {
return null;
}
},
// A cache update isn't tied to a specific window. Try to find
// the best browser in which to warn the user about space usage
_getBrowserForCacheUpdate: function(aCacheUpdate) {
// Prefer the current browser
var uri = this._getManifestURI(gBrowser.mCurrentBrowser.contentWindow);
if (uri && uri.equals(aCacheUpdate.manifestURI)) {
return gBrowser.mCurrentBrowser;
}
var browsers = getBrowser().browsers;
for (var i = 0; i < browsers.length; ++i) {
uri = this._getManifestURI(browsers[i].contentWindow);
if (uri && uri.equals(aCacheUpdate.manifestURI)) {
return browsers[i];
}
}
return null;
},
_warnUsage: function(aBrowser, aURI) {
if (!aBrowser)
return;
var notificationBox = gBrowser.getNotificationBox(aBrowser);
var notification = notificationBox.getNotificationWithValue("offline-app-usage");
if (!notification) {
var bundle_browser = document.getElementById("bundle_browser");
var buttons = [{
label: bundle_browser.getString("offlineApps.manageUsage"),
accessKey: bundle_browser.getString("offlineApps.manageUsageAccessKey"),
callback: OfflineApps.manage
}];
var warnQuota = gPrefService.getIntPref("offline-apps.quota.warn");
const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
var message = bundle_browser.getFormattedString("offlineApps.usage",
[ aURI.host,
warnQuota / 1024 ]);
notificationBox.appendNotification(message, "offline-app-usage",
"chrome://browser/skin/Info.png",
priority, buttons);
}
// Now that we've warned once, prevent the warning from showing up
// again.
var pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
pm.add(aURI, "offline-app",
Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN);
},
_checkUsage: function(aURI) {
var pm = Cc["@mozilla.org/permissionmanager;1"].
getService(Ci.nsIPermissionManager);
// if the user has already allowed excessive usage, don't bother checking
if (pm.testExactPermission(aURI, "offline-app") !=
Ci.nsIOfflineCacheUpdateService.ALLOW_NO_WARN) {
var usage = getOfflineAppUsage(aURI.asciiHost);
var warnQuota = gPrefService.getIntPref("offline-apps.quota.warn");
if (usage >= warnQuota * 1024) {
return true;
}
}
return false;
},
offlineAppRequested: function(aContentWindow) {
if (!gPrefService.getBoolPref("browser.offline-apps.notify")) {
return;
@ -5087,6 +5198,10 @@ var OfflineApps = {
pm.add(currentURI, "offline-app", Ci.nsIPermissionManager.DENY_ACTION);
},
manage: function() {
openAdvancedPreferences("networkTab");
},
_startFetching: function() {
var manifest = content.document.documentElement.getAttribute("manifest");
if (!manifest)
@ -5102,6 +5217,37 @@ var OfflineApps = {
var updateService = Cc["@mozilla.org/offlinecacheupdate-service;1"].
getService(Ci.nsIOfflineCacheUpdateService);
updateService.scheduleUpdate(manifestURI, contentURI);
},
/////////////////////////////////////////////////////////////////////////////
// nsIObserver
observe: function (aSubject, aTopic, aState)
{
if (aTopic == "dom-storage-warn-quota-exceeded") {
if (aSubject) {
var uri = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).
newURI(aSubject.location.href, null, null);
if (OfflineApps._checkUsage(uri)) {
var browserWindow =
this._getBrowserWindowForContentWindow(aSubject);
var browser = this._getBrowserForContentWindow(browserWindow,
aSubject);
OfflineApps._warnUsage(browser, uri);
}
}
} else if (aTopic == "offline-cache-update-completed") {
var cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
var uri = cacheUpdate.manifestURI;
if (OfflineApps._checkUsage(uri)) {
var browser = this._getBrowserForCacheUpdate(cacheUpdate);
if (browser) {
OfflineApps._warnUsage(browser, cacheUpdate.manifestURI);
}
}
}
}
};

View File

@ -90,6 +90,7 @@
<popupset id="mainPopupSet">
<menupopup id="backForwardMenu"
chromedir="&locale.dir;"
onpopupshowing="return FillHistoryMenu(event.target);"
oncommand="gotoHistoryIndex(event);"
onclick="checkForMiddleClick(this, event);"/>
@ -261,6 +262,7 @@
<!-- bug 415444: event.stopPropagation is here for the cloned version of
this menupopup -->
<menupopup context=""
chromedir="&locale.dir;"
position="after_start"
onpopupshowing="return FillHistoryMenu(event.target);"
oncommand="gotoHistoryIndex(event); event.stopPropagation();"
@ -305,6 +307,8 @@
ontextentered="return handleURLBarCommand(param);"
ontextreverted="return handleURLBarRevert();"
pageproxystate="invalid"
onsearchbegin="LocationBarHelpers._searchBegin();"
onsearchcomplete="LocationBarHelpers._searchComplete();"
onfocus="document.getElementById('identity-box').style.MozUserFocus= 'normal'"
onblur="document.getElementById('identity-box').style.MozUserFocus = 'ignore';">
<!-- Use onclick instead of normal popup= syntax since the popup
@ -315,18 +319,14 @@
onclick="getIdentityHandler().handleIdentityButtonEvent(event);"
onkeypress="getIdentityHandler().handleIdentityButtonEvent(event);">
<hbox align="center">
<deck id="page-proxy-deck" onclick="PageProxyClickHandler(event);">
<image id="page-proxy-button"
ondraggesture="PageProxyDragGesture(event);"
tooltiptext="&proxyIcon.tooltip;"/>
<stack id="page-proxy-stack"
onclick="PageProxyClickHandler(event);"
tooltiptext="&proxyIcon.tooltip;">
<image id="urlbar-throbber" busy="false"/>
<image id="page-proxy-favicon" validate="never"
ondraggesture="PageProxyDragGesture(event);"
onload="this.parentNode.selectedIndex = 1;
event.stopPropagation();"
onerror="this.removeAttribute('src');
this.parentNode.selectedIndex = 0;"
tooltiptext="&proxyIcon.tooltip;"/>
</deck>
onerror="this.removeAttribute('src');"/>
</stack>
<label id="identity-icon-label"/>
</hbox>
</box>

View File

@ -110,6 +110,7 @@
.footnote {
font-size: x-small;
text-align: justify;
line-height: 110%;
}
h2.title {
@ -468,10 +469,8 @@
Mozilla Firefox&reg; and the Firefox logo are registered trademarks of the
Mozilla Foundation. You are not granted rights or licenses to the trademarks
of the Mozilla Foundation or any party, including without limitation the
Firefox name or logo.</p>
<p class="footnote">
Gecko&reg; is a registered trademark of Netscape Communications Corporation.</p>
Firefox name or logo. Gecko&reg; is a registered trademark of Netscape
Communications Corporation.</p>
<p class="footnote">
U.S. GOVERNMENT END USERS. The Software is a &ldquo;commercial item,&rdquo;

View File

@ -362,7 +362,8 @@ nsContextMenu.prototype = {
// Set various context menu attributes based on the state of the world.
setTarget: function (aNode, aRangeParent, aRangeOffset) {
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
if (aNode.namespaceURI == xulNS) {
if (aNode.namespaceURI == xulNS ||
this.isTargetAFormControl(aNode)) {
this.shouldDisplay = false;
return;
}
@ -1093,6 +1094,18 @@ nsContextMenu.prototype = {
"contextMenu.hasBGImage = " + this.hasBGImage + "\n";
},
// Returns true if aNode is a from control (except text boxes).
// This is used to disable the context menu for form controls.
isTargetAFormControl: function(aNode) {
if (aNode instanceof HTMLInputElement)
return (aNode.type != "text" && aNode.type != "password");
return (aNode instanceof HTMLButtonElement) ||
(aNode instanceof HTMLSelectElement) ||
(aNode instanceof HTMLOptionElement) ||
(aNode instanceof HTMLOptGroupElement);
},
isTargetATextBox: function(node) {
if (node instanceof HTMLInputElement)
return (node.type == "text" || node.type == "password")

View File

@ -77,33 +77,36 @@
ondragexit="nsDragAndDrop.dragExit(event, this.parentNode.parentNode); event.stopPropagation();">
<xul:tooltip onpopupshowing="return this.parentNode.parentNode.parentNode.createTooltip(event);"/>
<xul:menupopup anonid="tabContextMenu" onpopupshowing="this.parentNode.parentNode.parentNode.updatePopupMenu(this);">
<xul:menuitem label="&newTab.label;" accesskey="&newTab.accesskey;"
<xul:menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
xbl:inherits="oncommand=onnewtab"/>
<xul:menuseparator/>
<xul:menuitem label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
<xul:menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
tabbrowser.reloadTab(tabbrowser.mContextTab);"/>
<xul:menuitem label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
<xul:menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
tbattr="tabbrowser-multiple"
oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
tabbrowser.reloadAllTabs(tabbrowser.mContextTab);"/>
<xul:menuitem label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
<xul:menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
tbattr="tabbrowser-multiple"
oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
tabbrowser.removeAllTabsBut(tabbrowser.mContextTab);"/>
<xul:menuseparator/>
<xul:menuitem label="&bookmarkThisTab.label;"
<xul:menuitem id="context_bookmarkTab"
label="&bookmarkThisTab.label;"
accesskey="&bookmarkThisTab.accesskey;"
oncommand="BookmarkThisTab();"/>
<xul:menuitem label="&bookmarkAllTabs.label;"
<xul:menuitem id="context_bookmarkAllTabs"
label="&bookmarkAllTabs.label;"
accesskey="&bookmarkAllTabs.accesskey;"
command="Browser:BookmarkAllTabs"/>
<xul:menuitem label="&undoCloseTab.label;"
<xul:menuitem id="context_undoCloseTab"
label="&undoCloseTab.label;"
accesskey="&undoCloseTab.accesskey;"
command="History:UndoCloseTab"
anonid="undoCloseTabMenuItem"/>
<xul:menuseparator/>
<xul:menuitem label="&closeTab.label;" accesskey="&closeTab.accesskey;"
<xul:menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
oncommand="var tabbrowser = this.parentNode.parentNode.parentNode.parentNode;
tabbrowser.removeTab(tabbrowser.mContextTab);"/>
</xul:menupopup>

View File

@ -384,10 +384,28 @@ function openPreferences(paneID)
var pane = win.document.getElementById(paneID);
win.document.documentElement.showPane(pane);
}
return win;
}
return openDialog("chrome://browser/content/preferences/preferences.xul",
"Preferences", features, paneID);
}
function openAdvancedPreferences(tabID)
{
var win = openPreferences("paneAdvanced");
if (win) {
var selectTab = function() {
var tabs = win.document.getElementById("advancedPrefs");
tabs.selectedTab = win.document.getElementById(tabID);
}
if (win.document.getElementById("advancedPrefs")) {
selectTab();
} else {
win.addEventListener("load", selectTab, false);
}
}
else
openDialog("chrome://browser/content/preferences/preferences.xul",
"Preferences", features, paneID);
}
/**
@ -637,3 +655,21 @@ function isValidFeed(aData, aPrincipal, aIsFeed)
return aIsFeed;
}
function getOfflineAppUsage(host)
{
var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].
getService(Components.interfaces.nsICacheService);
var cacheSession = cacheService.createSession("HTTP-offline",
Components.interfaces.nsICache.STORE_OFFLINE,
true).
QueryInterface(Components.interfaces.nsIOfflineCacheSession);
var usage = cacheSession.getDomainUsage(host);
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"].
getService(Components.interfaces.nsIDOMStorageManager);
usage += storageManager.getUsage(host);
return usage;
}

View File

@ -64,12 +64,6 @@ SHARED_LIBRARY_LIBS += ../shell/src/$(LIB_PREFIX)shellservice_s.$(LIB_SUFFIX) \
$(NULL)
endif
ifdef MOZ_SAFE_BROWSING
REQUIRES += safebrowsing
LOCAL_INCLUDES += -I$(srcdir)/../safebrowsing/src
SHARED_LIBRARY_LIBS += ../safebrowsing/src/$(LIB_PREFIX)safebrowsing_s.$(LIB_SUFFIX)
endif
EXTRA_DSO_LDOPTS += \
$(call EXPAND_LIBNAME_PATH,unicharutil_external_s,$(LIBXUL_DIST)/lib) \
$(LIBXUL_DIST)/lib/$(LIB_PREFIX)mozreg_s.$(LIB_SUFFIX) \

View File

@ -91,12 +91,6 @@
#define NS_ABOUTFEEDS_CID \
{ 0x12ff56ec, 0x58be, 0x402c, { 0xb0, 0x57, 0x1, 0xf9, 0x61, 0xde, 0x96, 0x9b } }
#define NS_DOCNAVSTARTPROGRESSLISTENER_CID \
{ 0x7baf8179, 0xa4fd, 0x4bc0, { 0xbe, 0x43, 0xa9, 0xb1, 0x22, 0xc5, 0xde, 0xb6 } }
#define NS_DOCNAVSTARTPROGRESSLISTENER_CONTRACTID \
"@mozilla.org/browser/safebrowsing/navstartlistener;1"
// 6fb0c970-e1b1-11db-8314-0800200c9a66
#define NS_PLACESIMPORTEXPORTSERVICE_CID \
{ 0x6fb0c970, 0xe1b1, 0x11db, { 0x83, 0x14, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }

View File

@ -69,9 +69,6 @@
#include "nsFeedSniffer.h"
#include "nsAboutFeeds.h"
#include "nsIAboutModule.h"
#ifdef MOZ_SAFE_BROWSING
#include "nsDocNavStartProgressListener.h"
#endif
/////////////////////////////////////////////////////////////////////////////
@ -102,9 +99,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsCaminoProfileMigrator)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsICabProfileMigrator)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
#ifdef MOZ_SAFE_BROWSING
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDocNavStartProgressListener)
#endif
/////////////////////////////////////////////////////////////////////////////
@ -142,13 +136,6 @@ static const nsModuleComponentInfo components[] =
nsAboutFeeds::Create
},
#ifdef MOZ_SAFE_BROWSING
{ "Safe browsing document nav start progress listener",
NS_DOCNAVSTARTPROGRESSLISTENER_CID,
NS_DOCNAVSTARTPROGRESSLISTENER_CONTRACTID,
nsDocNavStartProgressListenerConstructor },
#endif
{ "Profile Migrator",
NS_FIREFOX_PROFILEMIGRATOR_CID,
NS_PROFILEMIGRATOR_CONTRACTID,

View File

@ -35,8 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsIMIMEInfo.idl"
#include "nsIWebContentHandlerRegistrar.idl"
interface nsIRequest;
@ -64,8 +64,8 @@ interface nsIWebContentHandlerInfo : nsIHandlerApp
AString getHandlerURI(in AString uri);
};
[scriptable, uuid(632b16a8-5c6b-4dc5-a8db-01771af7a79d)]
interface nsIWebContentConverterService : nsISupports
[scriptable, uuid(de7cc06e-e778-45cb-b7db-7a114e1e75b1)]
interface nsIWebContentConverterService : nsIWebContentHandlerRegistrar
{
/**
* Specifies the handler to be used to automatically handle all links of a
@ -128,30 +128,6 @@ interface nsIWebContentConverterService : nsISupports
*/
void removeContentHandler(in AString contentType, in AString uri);
/**
* Registers a protocol handler for a web service
* @param protocol
* The protocol scheme to register a service handler for
* @param uri
* The uri of the service handler to register
* @param title
* The human readable title of the service
*/
void registerProtocolHandler(in AString scheme, in AString uri,
in AString title);
/**
* Registers a content handler for a web service
* @param contentType
* The content type to register a service handler for
* @param uri
* The uri of the service handler to register
* @param title
* The human readable title of the service
*/
void registerContentHandler(in AString contentType, in AString uri,
in AString title);
/**
* Gets the list of content handlers for a particular type.
* @param contentType

View File

@ -498,9 +498,8 @@ WebContentConverterRegistrar.prototype = {
/**
* See nsIWebContentHandlerRegistrar
* This is the web front end into the registration system, so a prompt to
* confirm the registration is provided, and the result is saved to
* preferences.
* If a DOM window is provided, then the request came from content, so we
* prompt the user to confirm the registration.
*/
registerContentHandler:
function WCCR_registerContentHandler(aContentType, aURIString, aTitle, aContentWindow) {
@ -513,12 +512,16 @@ WebContentConverterRegistrar.prototype = {
if (contentType != TYPE_MAYBE_FEED)
return;
var uri = this._checkAndGetURI(aURIString, aContentWindow);
var browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
var browserElement = this._getBrowserForContentWindow(browserWindow, aContentWindow);
var notificationBox = browserWindow.getBrowser().getNotificationBox(browserElement);
this._appendFeedReaderNotification(uri, aTitle, notificationBox);
if (aContentWindow) {
var uri = this._checkAndGetURI(aURIString, aContentWindow);
var browserWindow = this._getBrowserWindowForContentWindow(aContentWindow);
var browserElement = this._getBrowserForContentWindow(browserWindow, aContentWindow);
var notificationBox = browserWindow.getBrowser().getNotificationBox(browserElement);
this._appendFeedReaderNotification(uri, aTitle, notificationBox);
}
else
this._registerContentHandler(contentType, aURIString, aTitle);
},
/**
@ -608,25 +611,8 @@ WebContentConverterRegistrar.prototype = {
var outer = aButtonInfo._outer;
// The reader could have been added from another window mean while
if (!outer.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uri)) {
if (!outer.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uri))
outer._registerContentHandler(TYPE_MAYBE_FEED, uri, name);
outer._saveContentHandlerToPrefs(TYPE_MAYBE_FEED, uri, name);
// Make the new handler the last-selected reader in the preview page
// and make sure the preview page is shown the next time a feed is visited
var pb = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService).getBranch(null);
pb.setCharPref(PREF_SELECTED_READER, "web");
var supportsString =
Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
supportsString.data = uri;
pb.setComplexValue(PREF_SELECTED_WEB, Ci.nsISupportsString,
supportsString);
pb.setCharPref(PREF_SELECTED_ACTION, "ask");
outer._setAutoHandler(TYPE_MAYBE_FEED, null);
}
// avoid reference cycles
aButtonInfo._outer = null;
@ -726,6 +712,39 @@ WebContentConverterRegistrar.prototype = {
return template.replace(/%s/, contentType);
},
/**
* Register a web service handler for a content type.
*
* @param contentType
* the content type being handled
* @param uri
* the URI of the web service
* @param title
* the human readable name of the web service
*/
_registerContentHandler:
function WCCR__registerContentHandler(contentType, uri, title) {
this._updateContentTypeHandlerMap(contentType, uri, title);
this._saveContentHandlerToPrefs(contentType, uri, title);
if (contentType == TYPE_MAYBE_FEED) {
// Make the new handler the last-selected reader in the preview page
// and make sure the preview page is shown the next time a feed is visited
var pb = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefService).getBranch(null);
pb.setCharPref(PREF_SELECTED_READER, "web");
var supportsString =
Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString);
supportsString.data = uri;
pb.setComplexValue(PREF_SELECTED_WEB, Ci.nsISupportsString,
supportsString);
pb.setCharPref(PREF_SELECTED_ACTION, "ask");
this._setAutoHandler(TYPE_MAYBE_FEED, null);
}
},
/**
* Update the content type -> handler map. This mapping is not persisted, use
* registerContentHandler or _saveContentHandlerToPrefs for that purpose.
@ -736,8 +755,8 @@ WebContentConverterRegistrar.prototype = {
* @param title
* The human readable name of the web service
*/
_registerContentHandler:
function WCCR__registerContentHandler(contentType, uri, title) {
_updateContentTypeHandlerMap:
function WCCR__updateContentTypeHandlerMap(contentType, uri, title) {
if (!(contentType in this._contentTypes))
this._contentTypes[contentType] = [];
@ -805,7 +824,7 @@ WebContentConverterRegistrar.prototype = {
var uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
var title = branch.getComplexValue("title",
Ci.nsIPrefLocalizedString).data;
this._registerContentHandler(type, uri, title);
this._updateContentTypeHandlerMap(type, uri, title);
}
catch(ex) {
// do nothing, the next branch might have values

View File

@ -237,7 +237,9 @@ BrowserGlue.prototype = {
prefBranch.getBoolPref("browser.sessionstore.resume_session_once"))
showPrompt = false;
else
showPrompt = prefBranch.getBoolPref("browser.warnOnQuit");
showPrompt = aQuitType == "restart" ?
prefBranch.getBoolPref("browser.warnOnRestart") :
prefBranch.getBoolPref("browser.warnOnQuit");
} catch (ex) {}
var buttonChoice = 0;
@ -297,10 +299,15 @@ BrowserGlue.prototype = {
break;
case 0:
this._saveSession = true;
// could also set browser.warnOnQuit to false here,
// but not setting it is a little safer.
if (neverAsk.value)
prefBranch.setIntPref("browser.startup.page", 3);
if (neverAsk.value) {
if (aQuitType == "restart")
prefBranch.setBoolPref("browser.warnOnRestart", false);
else {
// could also set browser.warnOnQuit to false here,
// but not setting it is a little safer.
prefBranch.setIntPref("browser.startup.page", 3);
}
}
break;
}
}
@ -532,7 +539,6 @@ BrowserGlue.prototype = {
var bookmarksMenuFolder = bmsvc.bookmarksMenuFolder;
var unfiledBookmarksFolder = bmsvc.unfiledBookmarksFolder;
var toolbarFolder = bmsvc.toolbarFolder;
var tagsFolder = bmsvc.tagsFolder;
var defaultIndex = bmsvc.DEFAULT_INDEX;
// index = 0, make it the first folder
@ -567,14 +573,11 @@ BrowserGlue.prototype = {
var sep = bmsvc.insertSeparator(placesFolder, defaultIndex);
var recentTagsItem = bmsvc.insertBookmark(placesFolder,
this._uri("place:folder=" + tagsFolder +
"&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER +
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&applyOptionsToContainers=1" +
"&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
this._uri("place:"+
"type=" + Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
"&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
"&maxResults=" + maxResults),
defaultIndex, recentTagsTitle);
defaultIndex, recentTagsTitle);
}
};

View File

@ -72,8 +72,8 @@
flex="1"
hidecolumnpicker="true"
context="placesContext"
onkeypress="if (event.keyCode == 13) this.controller.openSelectedNodeWithEvent(event);"
onclick="SidebarUtils.handleClick(this, event);"
onkeypress="SidebarUtils.handleTreeKeyPress(event);"
onclick="SidebarUtils.handleTreeClick(this, event);"
onmousemove="SidebarUtils.handleTreeMouseMove(event);"
onmouseout="SidebarUtils.clearURLFromStatusBar();">
<treecols>

View File

@ -128,7 +128,8 @@ PlacesController.prototype = {
case "placesCmd_open":
case "placesCmd_open:window":
case "placesCmd_open:tab":
return this._view.selectedURINode;
var selectedNode = this._view.selectedNode;
return selectedNode && PlacesUtils.nodeIsURI(selectedNode);
case "placesCmd_new:folder":
case "placesCmd_new:livemark":
return this._canInsert();
@ -140,8 +141,8 @@ PlacesController.prototype = {
this._view.getResult().sortingMode ==
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
case "placesCmd_show:info":
if (this._view.hasSingleSelection) {
var selectedNode = this._view.selectedNode;
var selectedNode = this._view.selectedNode;
if (selectedNode) {
if (PlacesUtils.nodeIsFolder(selectedNode) ||
(PlacesUtils.nodeIsBookmark(selectedNode) &&
!PlacesUtils.nodeIsLivemarkItem(selectedNode)))
@ -149,24 +150,13 @@ PlacesController.prototype = {
}
return false;
case "placesCmd_reloadMicrosummary":
if (this._view.hasSingleSelection) {
var selectedNode = this._view.selectedNode;
if (PlacesUtils.nodeIsBookmark(selectedNode)) {
var mss = PlacesUtils.microsummaries;
if (mss.hasMicrosummary(selectedNode.itemId))
return true;
}
}
return false;
var selectedNode = this._view.selectedNode;
return selectedNode && PlacesUtils.nodeIsBookmark(selectedNode) &&
PlacesUtils.microsummaries.hasMicrosummary(selectedNode.itemId);
case "placesCmd_reload":
if (this._view.hasSingleSelection) {
var selectedNode = this._view.selectedNode;
// Livemark containers
if (PlacesUtils.nodeIsLivemarkContainer(selectedNode))
return true;
}
return false;
// Livemark containers
var selectedNode = this._view.selectedNode;
return selectedNode && PlacesUtils.nodeIsLivemarkContainer(selectedNode);
case "placesCmd_sortBy:name":
var selectedNode = this._view.selectedNode;
return selectedNode &&
@ -223,13 +213,13 @@ PlacesController.prototype = {
this.selectAll();
break;
case "placesCmd_open":
this.openSelectedNodeIn("current");
PlacesUtils.openNodeIn(this._view.selectedNode, "current");
break;
case "placesCmd_open:window":
this.openSelectedNodeIn("window");
PlacesUtils.openNodeIn(this._view.selectedNode, "window");
break;
case "placesCmd_open:tab":
this.openSelectedNodeIn("tab");
PlacesUtils.openNodeIn(this._view.selectedNode, "tab");
break;
case "placesCmd_new:folder":
this.newItem("folder");
@ -277,9 +267,6 @@ PlacesController.prototype = {
* false otherwise.
*/
_hasRemovableSelection: function PC__hasRemovableSelection(aIsMoveCommand) {
if (!this._view.hasSelection)
return false;
var nodes = this._view.getSelectionNodes();
var root = this._view.getResultNode();
@ -328,14 +315,13 @@ PlacesController.prototype = {
* Determines whether or not the root node for the view is selected
*/
rootNodeIsSelected: function PC_rootNodeIsSelected() {
if (this._view.hasSelection) {
var nodes = this._view.getSelectionNodes();
var root = this._view.getResultNode();
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == root)
return true;
}
var nodes = this._view.getSelectionNodes();
var root = this._view.getResultNode();
for (var i = 0; i < nodes.length; ++i) {
if (nodes[i] == root)
return true;
}
return false;
},
@ -411,12 +397,10 @@ PlacesController.prototype = {
*/
_buildSelectionMetadata: function PC__buildSelectionMetadata() {
var metadata = [];
var nodes = [];
var root = this._view.getResult().root;
if (this._view.hasSelection)
nodes = this._view.getSelectionNodes();
else // See the second note above
nodes = [root];
var nodes = this._view.getSelectionNodes();
if (nodes.length == 0)
nodes.push(root); // See the second note above
for (var i=0; i < nodes.length; i++) {
var nodeData = {};
@ -429,6 +413,17 @@ PlacesController.prototype = {
switch(nodeType) {
case Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY:
nodeData["query"] = true;
if (node.parent) {
switch (asQuery(node.parent).queryOptions.resultType) {
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY:
nodeData["host"] = true;
break;
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY:
case Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY:
nodeData["day"] = true;
break;
}
}
break;
case Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER:
nodeData["dynamiccontainer"] = true;
@ -437,9 +432,6 @@ PlacesController.prototype = {
case Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT:
nodeData["folder"] = true;
break;
case Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST:
nodeData["host"] = true;
break;
case Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR:
nodeData["separator"] = true;
break;
@ -458,8 +450,6 @@ PlacesController.prototype = {
nodeData["livemarkChild"] = true;
}
break;
case Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY:
nodeData["day"] = true;
}
// Mutability is whether or not a container can have selected items
@ -628,49 +618,6 @@ PlacesController.prototype = {
this._view.selectAll();
},
/**
* Loads the selected node's URL in the appropriate tab or window or as a web
* panel given the user's preference specified by modifier keys tracked by a
* DOM mouse/key event.
* @param aEvent
* The DOM mouse/key event with modifier keys set that track the
* user's preferred destination window or tab.
*/
openSelectedNodeWithEvent: function PC_openSelectedNodeWithEvent(aEvent) {
this.openSelectedNodeIn(whereToOpenLink(aEvent));
},
/**
* Loads the selected node's URL in the appropriate tab or window or as a
* web panel.
* see also openUILinkIn
*/
openSelectedNodeIn: function PC_openSelectedNodeIn(aWhere) {
var node = this._view.selectedURINode;
if (node && PlacesUtils.checkURLSecurity(node)) {
var isBookmark = PlacesUtils.nodeIsBookmark(node);
if (isBookmark)
PlacesUtils.markPageAsFollowedBookmark(node.uri);
else
PlacesUtils.markPageAsTyped(node.uri);
// Check whether the node is a bookmark which should be opened as
// a web panel
if (aWhere == "current" && isBookmark) {
if (PlacesUtils.annotations
.itemHasAnnotation(node.itemId, LOAD_IN_SIDEBAR_ANNO)) {
var w = getTopWin();
if (w) {
w.openWebPanel(node.title, node.uri);
return;
}
}
}
openUILinkIn(node.uri, aWhere);
}
},
/**
* Opens the bookmark properties for the selected URI Node.
*/
@ -699,11 +646,9 @@ PlacesController.prototype = {
* Reloads the selected livemark if any.
*/
reloadSelectedLivemark: function PC_reloadSelectedLivemark() {
if (this._view.hasSingleSelection) {
var selectedNode = this._view.selectedNode;
if (PlacesUtils.nodeIsLivemarkContainer(selectedNode))
PlacesUtils.livemarks.reloadLivemarkFolder(selectedNode.itemId);
}
var selectedNode = this._view.selectedNode;
if (selectedNode && PlacesUtils.nodeIsLivemarkContainer(selectedNode))
PlacesUtils.livemarks.reloadLivemarkFolder(selectedNode.itemId);
},
/**
@ -768,7 +713,7 @@ PlacesController.prototype = {
*/
openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
var node = this._view.selectedNode;
if (this._view.hasSingleSelection && PlacesUtils.nodeIsContainer(node))
if (node && PlacesUtils.nodeIsContainer(node))
PlacesUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent);
else
PlacesUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent);
@ -964,14 +909,16 @@ PlacesController.prototype = {
// day nodes have time property set to the last day in the interval
var endDate = node.time;
// if this is not the last day container, then beginDate
// is the time property of the next day container
for (var j = 0; j < root.childCount-1 && !beginDate; ++j) {
if (root.getChild(j) != node)
continue;
var nextNode = root.getChild(j+1);
beginDate = nextNode.time
}
var nodeIdx = 0;
var cc = root.childCount;
// Find index of current day node
while (nodeIdx < cc && root.getChild(nodeIdx) != node)
++nodeIdx;
// We have an older day
if (nodeIdx+1 < cc)
beginDate = root.getChild(nodeIdx+1).time;
// we want to exclude beginDate from the removal
bhist.removePagesByTimeframe(beginDate+1, endDate);
@ -1036,11 +983,14 @@ PlacesController.prototype = {
var oldViewer = result.viewer;
try {
result.viewer = null;
var nodes = null;
if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_COPY)
nodes = this._view.getCopyableSelection();
else
nodes = this._view.getDragableSelection();
var nodes = this._view.getDragableSelection();
if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_MOVE) {
nodes = nodes.filter(function(node) {
var parent = node.parent;
return parent && !PlacesUtils.nodeIsReadOnly(parent);
});
}
var dataSet = new TransferDataSet();
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
@ -1086,14 +1036,14 @@ PlacesController.prototype = {
var oldViewer = result.viewer;
try {
result.viewer = null;
var nodes = this._view.getCopyableSelection();
var nodes = this._view.getSelectionNodes();
var xferable = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
var foundFolder = false, foundLink = false;
var copiedFolders = [];
var placeString = mozURLString = htmlString = unicodeString = "";
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
if (this._shouldSkipNode(node, copiedFolders))
@ -1114,7 +1064,7 @@ PlacesController.prototype = {
uri) + suffix);
htmlString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_HTML,
uri) + suffix);
var placeSuffix = i < (nodes.length - 1) ? "," : "";
return PlacesUtils.wrapNode(node, type, overrideURI) + placeSuffix;
}

View File

@ -102,11 +102,9 @@ function historyAddBookmarks()
// no need to check gHistoryTree.view.selection.count
// node will be null if there is a multiple selection
// or if the selected item is not a URI node
var node = gHistoryTree.selectedURINode;
if (!node)
return;
PlacesUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title);
var node = gHistoryTree.selectedNode;
if (node && PlacesUtils.nodeIsURI(node))
PlacesUtils.showMinimalAddBookmarkUI(PlacesUtils._uri(node.uri), node.title);
}
function searchHistory(aInput)
@ -116,7 +114,6 @@ function searchHistory(aInput)
const NHQO = Ci.nsINavHistoryQueryOptions;
var sortingMode;
var groups = [];
var resultType;
if (aInput) {
@ -134,22 +131,20 @@ function searchHistory(aInput)
resultType = NHQO.RESULTS_AS_URI;
sortingMode = NHQO.SORT_BY_DATE_DESCENDING;
break;
case "dayandsite": // fall through
groups.push(NHQO.GROUP_BY_DAY);
case "dayandsite":
resultType = NHQO.RESULTS_AS_DATE_SITE_QUERY;
break;
case "site":
groups.push(NHQO.GROUP_BY_HOST);
resultType = NHQO.RESULTS_AS_VISIT;
resultType = NHQO.RESULTS_AS_SITE_QUERY;
sortingMode = NHQO.SORT_BY_TITLE_ASCENDING;
break;
case "day":
default:
resultType = NHQO.RESULTS_AS_VISIT;
groups.push(NHQO.GROUP_BY_DAY);
sortingMode = NHQO.SORT_BY_TITLE_ASCENDING;
resultType = NHQO.RESULTS_AS_DATE_QUERY;
break;
}
}
options.setGroupingMode(groups, groups.length);
options.sortingMode = sortingMode;
options.resultType = resultType;

View File

@ -119,9 +119,9 @@
flex="1"
type="places"
context="placesContext"
onkeypress="if (event.keyCode == 13) this.controller.openSelectedNodeWithEvent(event);"
hidecolumnpicker="true"
onclick="SidebarUtils.handleClick(this, event, true);"
onkeypress="SidebarUtils.handleTreeKeyPress(event);"
onclick="SidebarUtils.handleTreeClick(this, event);"
onmousemove="SidebarUtils.handleTreeMouseMove(event);"
onmouseout="SidebarUtils.clearURLFromStatusBar();">
<treecols>

View File

@ -187,11 +187,12 @@
<parameter name="aXferData"/>
<parameter name="aDragAction"/>
<body><![CDATA[
this._rootView._selection = aEvent.target.node;
this._rootView._cachedInsertionPoint = undefined;
if (aEvent.ctrlKey)
aDragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
// activate the view and cache the dragged node
this._rootView._draggedNode = aEvent.target.node;
this._rootView.focus();
aXferData.data = this._rootView.controller
.getTransferData(aDragAction.action);
]]></body>
@ -248,28 +249,27 @@
<body><![CDATA[
// Can't drop if the menu isn't a folder
var resultNode = this._resultNode;
if (!PlacesUtils.nodeIsFolder(resultNode))
return null;
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
// Loop through all the nodes to see which one this should
// get dropped in/above/below.
// set the limits for valid items
var start = 0;
var popup = this;
var end = popup.childNodes.length;
if (popup == this._rootView &&
this._rootView.localName == "menupopup") {
// Ignore static content at the top and bottom of the menu.
start = this._rootView._startMarker + 1;
if (this._rootView._endMarker != -1)
end = this._rootView._endMarker;
}
if (this._startMarker != -1)
start = this._startMarker + 1;
if (this._endMarker != -1)
end = this._endMarker;
var popupFirstChildY = popup.firstChild.boxObject.y;
// Loop through all the nodes to find the correct dropPoint
var popupY = popup.boxObject.y;
// we should add the scrollBox button height if visible
popupY += this._scrollBox.scrollBoxObject.y - popup.boxObject.y;
for (var i = start; i < end; i++) {
var xulNode = popup.childNodes[i];
var nodeY = xulNode.boxObject.y - popupFirstChildY;
var nodeY = xulNode.boxObject.y - popupY;
var nodeHeight = xulNode.boxObject.height;
if (xulNode.node &&
PlacesUtils.nodeIsFolder(xulNode.node) &&
@ -295,7 +295,7 @@
else {
// This is a non-folder node. If the mouse is above the middle,
// drop above the folder. Otherwise, drop below.
if (aEvent.layerY < nodeY + (nodeHeight / 2)) {
if (aEvent.layerY <= nodeY + (nodeHeight / 2)) {
// Drop above this bookmark.
dropPoint.ip = new InsertionPoint(resultNode.itemId,
i - start, -1);
@ -507,8 +507,6 @@
]]></body>
</method>
<field name="_selection">null</field>
<!-- nsIPlacesView -->
<method name="getResult">
<body><![CDATA[
@ -588,6 +586,11 @@
}
}
// if document.popupNode pointed to this child, null it out,
// otherwise controller's command-updating may rely on the removed
// item still being "selected".
if (document.popupNode == child)
document.popupNode = null;
child.parentNode.removeChild(child);
]]></body>
</method>
@ -872,21 +875,15 @@
<!-- nsIPlacesView -->
<property name="hasSelection">
<getter><![CDATA[
return this._selection != null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="hasSingleSelection">
<getter><![CDATA[
return this.hasSelection;
return this.selectedNode != null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<method name="getSelectionNodes">
<body><![CDATA[
return this.hasSelection ? [this.selectedNode] : [];
var selectedNode = this.selectedNode;
return selectedNode ? [selectedNode] : [];
]]></body>
</method>
@ -897,77 +894,58 @@
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getCopyableSelection">
<body><![CDATA[
return this.getSelectionNodes();
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getDragableSelection">
<body><![CDATA[
if (PlacesUtils.nodeIsReadOnly(this._resultNode))
return null;
return this.getSelectionNodes();
return [this._draggedNode];
]]></body>
</method>
<!-- nsIPlacesView -->
<property name="selectedNode">
<getter><![CDATA[
return this.hasSelection ? this._selection : null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="selectedURINode">
<getter><![CDATA[
var node = this.selectedNode;
return node && PlacesUtils.nodeIsURI(node) ? node : null;
if (this._contextMenuShown) {
var popupNode = document.popupNode;
return popupNode.node || popupNode.parentNode._resultNode || null;
}
return null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="insertionPoint">
<getter><![CDATA[
if (this._cachedInsertionPoint !== undefined)
return this._cachedInsertionPoint;
// By default, the insertion point is at the top level, at the end.
var index = -1;
var folderId = 0;
if (PlacesUtils.nodeIsFolder(this._resultNode))
folderId = PlacesUtils.getConcreteItemId(this._resultNode);
if (this.hasSelection) {
if (PlacesUtils.nodeIsFolder(this.selectedNode)) {
var selectedNode = this.selectedNode;
if (selectedNode) {
if (PlacesUtils.nodeIsFolder(selectedNode)) {
// If there is a folder selected, the insertion point is the
// end of the folder.
folderId = PlacesUtils.getConcreteItemId(this.selectedNode);
} else {
folderId = PlacesUtils.getConcreteItemId(selectedNode);
}
else {
// If there is another type of node selected, the insertion point
// is after that node.
folderId = PlacesUtils.getConcreteItemId(this.selectedNode.parent);
index = PlacesUtils.getIndexOfNode(this.selectedNode)
folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
index = PlacesUtils.getIndexOfNode(selectedNode)
}
}
this._cachedInsertionPoint = new InsertionPoint(folderId, index);
return this._cachedInsertionPoint;
return new InsertionPoint(folderId, index);
]]></getter>
</property>
<!-- nsIPlacesView -->
<method name="selectAll">
<body><![CDATA[
// Nothing
]]></body>
<body/>
</method>
<method name="selectItems">
<body><![CDATA[
// Nothing
]]></body>
<body/>
</method>
<property name="selType" readonly="true" onget="return 'single';"/>
@ -976,6 +954,7 @@
<parameter name="aPopup"/>
<body><![CDATA[
this._ensureInitialized();
this._contextMenuShown = true;
this.focus();
return this.controller.buildContextMenu(aPopup);
]]></body>
@ -985,6 +964,7 @@
<parameter name="aPopup"/>
<body>
<![CDATA[
this._contextMenuShown = false;
if (window.content)
window.content.focus();
]]>
@ -1013,28 +993,6 @@
// when the folder closes because it is no longer applicable.
popup.removeAttribute("autoopened");
]]></handler>
<!-- Set selected node on DOMMenuItemActive/contextmenu events
so that they're set up when command and click events fire. -->
<handler event="DOMMenuItemActive"><![CDATA[
// Set the selection to the node that was activated. If that
// node has a command but no data associated with it, it should
// act on the entire menu.
if (event.target.parentNode._resultNode) {
this._cachedInsertionPoint = undefined;
this._selection = event.target.node ||
event.target.parentNode._resultNode;
}
]]></handler>
<handler event="contextmenu"><![CDATA[
// DOMMenuItemActive is not dispatched for disabled menuitems and
// menuseparators. Set the selection here manually.
var popupNode = document.popupNode;
// |popupNode == menupopup| happens when the area between
// menuseparators is clicked.
this._selection = popupNode.node || popupNode.parentNode._resultNode;
this._cachedInsertionPoint = undefined;
]]></handler>
</handlers>
</binding>

View File

@ -232,20 +232,19 @@ var PlacesOrganizer = {
* The mouse event.
*/
onTreeClick: function PO_onTreeClick(aEvent) {
var currentView = aEvent.currentTarget;
var controller = currentView.controller;
if (aEvent.target.localName != "treechildren")
return;
if (currentView.hasSingleSelection && aEvent.button == 1) {
if (PlacesUtils.nodeIsURI(currentView.selectedNode))
controller.openSelectedNodeWithEvent(aEvent);
else if (PlacesUtils.nodeIsContainer(currentView.selectedNode)) {
var currentView = aEvent.currentTarget;
var selectedNode = currentView.selectedNode;
if (selectedNode && aEvent.button == 1) {
if (PlacesUtils.nodeIsURI(selectedNode))
PlacesUtils.openNodeWithEvent(selectedNode, aEvent);
else if (PlacesUtils.nodeIsContainer(selectedNode)) {
// The command execution function will take care of seeing the
// selection is a folder/container and loading its contents in
// tabs for us.
controller.openLinksInTabs();
PlacesUtils.openContainerNodeInTabs(selectedNode);
}
}
},
@ -258,7 +257,7 @@ var PlacesOrganizer = {
},
openSelectedNode: function PU_openSelectedNode(aEvent) {
this._content.controller.openSelectedNodeWithEvent(aEvent);
PlacesUtils.openNodeWithEvent(this._content.selectedNode, aEvent);
},
/**
@ -525,23 +524,21 @@ var PlacesOrganizer = {
var contentTree = document.getElementById("placeContent");
var detailsDeck = document.getElementById("detailsDeck");
if (contentTree.hasSelection) {
detailsDeck.selectedIndex = 1;
if (contentTree.hasSingleSelection) {
var selectedNode = contentTree.selectedNode;
if (selectedNode.itemId != -1 &&
!PlacesUtils.nodeIsSeparator(selectedNode)) {
if (this._paneDisabled) {
this._setDetailsFieldsDisabledState(false);
this._paneDisabled = false;
}
gEditItemOverlay.initPanel(selectedNode.itemId,
{ hiddenRows: ["folderPicker"] });
this._detectAndSetDetailsPaneMinimalState(selectedNode);
return;
detailsDeck.selectedIndex = 1;
var selectedNode = contentTree.selectedNode;
if (selectedNode) {
if (selectedNode.itemId != -1 &&
!PlacesUtils.nodeIsSeparator(selectedNode)) {
if (this._paneDisabled) {
this._setDetailsFieldsDisabledState(false);
this._paneDisabled = false;
}
gEditItemOverlay.initPanel(selectedNode.itemId,
{ hiddenRows: ["folderPicker"] });
this._detectAndSetDetailsPaneMinimalState(selectedNode);
return;
}
}
else {

View File

@ -37,7 +37,7 @@
# ***** END LICENSE BLOCK *****
var SidebarUtils = {
handleClick: function SU_handleClick(aTree, aEvent, aGutterSelect) {
handleTreeClick: function SU_handleTreeClick(aTree, aEvent, aGutterSelect) {
var tbo = aTree.treeBoxObject;
var row = { }, col = { }, obj = { };
@ -67,10 +67,15 @@ var SidebarUtils = {
// do this *before* attempting to load the link since openURL uses
// selection as an indication of which link to load.
tbo.view.selection.select(row.value);
aTree.controller.openSelectedNodeWithEvent(aEvent);
PlacesUtils.openNodeWithEvent(aTree.selectedNode, aEvent);
}
},
handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
PlacesUtils.openNodeWithEvent(aEvent.target.selectedNode, aEvent);
},
/**
* The following function displays the URL of a node that is being
* hovered over.

View File

@ -122,8 +122,6 @@
<field name="_dropIndicatorBar">document.getAnonymousElementByAttribute(this, "class", "toolbar-drop-indicator-bar")</field>
<field name="_chevron">document.getAnonymousElementByAttribute(this, "class", "chevron")</field>
<field name="_selection">null</field>
<field name="_openedMenuButton">null</field>
<field name="_result">null</field>
@ -232,6 +230,11 @@
}
}
// if document.popupNode pointed to this child, null it out,
// otherwise controller's command-updating may rely on the removed
// item still being "selected".
if (document.popupNode == child)
document.popupNode = null;
child.parentNode.removeChild(child);
]]></body>
</method>
@ -331,85 +334,65 @@
<!-- nsIPlacesView -->
<property name="hasSelection">
<getter><![CDATA[
return this._selection != null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="hasSingleSelection">
<getter><![CDATA[
return this.hasSelection;
return this.selectedNode != null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<method name="getSelectionNodes">
<body><![CDATA[
return this.hasSelection ? [this.selectedNode] : [];
var selectedNode = this.selectedNode;
return selectedNode ? [selectedNode] : [];
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getRemovableSelectionRanges">
<body><![CDATA[
<body><![CDATA[
return [this.getSelectionNodes()];
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getCopyableSelection">
<body><![CDATA[
return this.getSelectionNodes();
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getDragableSelection">
<body><![CDATA[
if (PlacesUtils.nodeIsReadOnly(this._result.root))
return null;
return this.getSelectionNodes();
return [this._draggedNode];
]]></body>
</method>
<!-- nsIPlacesView -->
<property name="selectedNode">
<getter><![CDATA[
return this.hasSelection ? this._selection : null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="selectedURINode">
<getter><![CDATA[
var node = this.selectedNode;
return node && PlacesUtils.nodeIsURI(node) ? node : null;
if (this._contextMenuShown) {
var popupNode = document.popupNode;
return popupNode.node || popupNode.parentNode._resultNode || null;
}
return null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="insertionPoint">
<getter><![CDATA[
if (this._cachedInsertionPoint !== undefined)
return this._cachedInsertionPoint;
// By default, the insertion point is at the top level, at the end.
var index = -1;
var folderId = PlacesUtils.getConcreteItemId(this._result.root);
if (this.hasSelection) {
if (PlacesUtils.nodeIsFolder(this.selectedNode)) {
var selectedNode = this.selectedNode;
if (selectedNode) {
if (PlacesUtils.nodeIsFolder(selectedNode)) {
// If there is a folder selected, the insertion point is the
// end of the folder.
folderId = PlacesUtils.getConcreteItemId(this.selectedNode);
} else {
folderId = PlacesUtils.getConcreteItemId(selectedNode);
}
else {
// If there is another type of node selected, the insertion point
// is after that node.
index = PlacesUtils.getIndexOfNode(this.selectedNode);
folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
index = PlacesUtils.getIndexOfNode(selectedNode);
}
}
this._cachedInsertionPoint = new InsertionPoint(folderId, index, 1);
return this._cachedInsertionPoint;
return new InsertionPoint(folderId, index, 1);
]]></getter>
</property>
@ -704,7 +687,7 @@
this._overFolder.node.open = true;
this._overFolder.openTimer = null;
}
// Timer to close a menubutton that's been dragged off of.
if (timer == this._overFolder.closeTimer) {
// Only close the menubutton if the drag session isn't currently over
@ -728,7 +711,7 @@
this._clearOverFolder();
}
},
// The mouse is no longer dragging over the stored menubutton.
// Close the menubutton, clear out drag styles, and clear all
// timers for opening/closing it.
@ -749,7 +732,7 @@
this._overFolder.closeTimer = null;
}
},
// This function returns information about where to drop when
// dragging over this menu--insertion point, child index to drop
// before, and folder to drop into.
@ -758,7 +741,7 @@
var result = this._self.getResult();
if (!PlacesUtils.nodeIsFolder(result.root))
return null;
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
// Loop through all the nodes to see which one this should
// get dropped in/next to
@ -787,7 +770,8 @@
dropPoint.folderNode = xulNode;
return dropPoint;
}
} else{
}
else {
// This is a non-folder node. If the mouse is left of the middle,
// drop to the left of the folder. If it's right, drop to the right.
if (event.clientX < xulNode.boxObject.x + (xulNode.boxObject.width / 2)) {
@ -809,6 +793,10 @@
},
onDragStart: function TBV_DO_onDragStart(event, xferData, dragAction) {
// sub menus have their own d&d handlers
if (event.target.parentNode != this._self)
return false;
if (event.target.localName == "toolbarbutton" &&
event.target.getAttribute("type") == "menu") {
#ifdef XP_WIN
@ -823,19 +811,22 @@
#endif
}
if (event.ctrlKey) {
if (event.ctrlKey)
dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
}
// activate the view and cache the dragged node
this._self._draggedNode = event.target.node;
this._self.focus();
xferData.data = this._self._controller.getTransferData(dragAction.action);
#ifdef XP_WIN
return true;
#endif
},
canDrop: function TBV_DO_canDrop(event, session) {
return PlacesControllerDragHelper.canDrop();
},
onDragOver: function TBV_DO_onDragOver(event, flavor, session) {
PlacesControllerDragHelper.currentDropTarget = event.target;
var dropPoint = this._getDropPoint(event);
@ -874,7 +865,8 @@
else
ind.style.marginLeft = this._self.childNodes[dropPoint.beforeIndex].boxObject.x -
this._self.boxObject.x - halfInd + 'px';
} else {
}
else {
halfInd = Math.floor(halfInd);
if (dropPoint.beforeIndex == -1 || !this._self.childNodes.length)
ind.style.marginRight = '0px';
@ -946,6 +938,7 @@
<method name="buildContextMenu">
<parameter name="aPopup"/>
<body><![CDATA[
this._contextMenuShown = true;
this.focus();
return this.controller.buildContextMenu(aPopup);
]]></body>
@ -954,6 +947,7 @@
<method name="destroyContextMenu">
<parameter name="aPopup"/>
<body><![CDATA[
this._contextMenuShown = false;
if (window.content)
window.content.focus();
]]></body>
@ -1052,22 +1046,6 @@
<handler event="mouseout"><![CDATA[
window.XULBrowserWindow.setOverLink("", null);
]]></handler>
<handler event="mousedown"><![CDATA[
// When the user clicks down on a button, set it as the selection and
// tell the controller that we are the active view.
//
var target = event.target;
if (target == this)
this._selection = this.getResult().root;
else if (target.parentNode == this &&
(target.localName == "toolbarbutton" ||
target.localName == "toolbarseparator"))
this._selection = target.node;
else // Sub-menus are handled by the DOMMenuItemActive handler
return;
this._cachedInsertionPoint = undefined;
]]></handler>
<handler event="draggesture"><![CDATA[
if (event.target.localName == "toolbarbutton" ||
event.target.localName == "toolbarseparator")
@ -1120,35 +1098,6 @@
this._openedMenuButton = null;
]]></handler>
<!-- Set selected node on DOMMenuItemActive/contextmenu events
so that they're set up when command and click events fire. -->
<handler event="DOMMenuItemActive"><![CDATA[
// Set the selection to the node that was activated. If that
// node has a command but no data associated with it, it should
// act on the entire menu.
if (event.target.parentNode._resultNode) {
// the chevron has its own view
if (this._isChevronChild(event.target))
return;
this._cachedInsertionPoint = undefined;
this._selection = event.target.node ||
event.target.parentNode._resultNode;
}
]]></handler>
<handler event="contextmenu"><![CDATA[
// DOMMenuItemActive is not dispatched for disabled menuitems and
// menuseparators. Set the selection here manually.
var popupNode = document.popupNode;
// the chevron has its own view
if (this._isChevronChild(popupNode))
return;
// |popupNode == menupopup| happens when the area between menuseparators
// is clicked.
this._selection = popupNode.node || popupNode.parentNode._resultNode;
this._cachedInsertionPoint = undefined;
]]></handler>
<handler event="mousemove"><![CDATA[
if (this._openedMenuButton == null || PlacesControllerDragHelper.getSession())
return;

View File

@ -97,15 +97,6 @@
var query = PlacesUtils.history.getNewQuery();
query.searchTerms = filterString;
// Remove "group by folder" from the options list, because
// nsNavHistory::RecursiveGroup doesn't support it.
function isFolderGrouping(grouping, index, ary) {
return grouping != Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER;
}
var groupings = options.getGroupingMode({});
var folderGroupings = groupings.filter(isFolderGrouping);
options.setGroupingMode(folderGroupings, folderGroupings.length);
if (folderRestrict) {
query.setFolders(folderRestrict, folderRestrict.length);
options.queryType = options.QUERY_TYPE_BOOKMARKS;
@ -340,13 +331,6 @@
return this.view.selection.count >= 1;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="hasSingleSelection">
<getter><![CDATA[
return this.view.selection.count == 1;
]]></getter>
</property>
<!-- nsIPlacesView -->
<method name="getSelectionNodes">
@ -418,23 +402,10 @@
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getCopyableSelection">
<body><![CDATA[
// XXXben implement me!
return this.getSelectionNodes();
]]></body>
</method>
<!-- nsIPlacesView -->
<method name="getDragableSelection">
<body><![CDATA[
var nodes = this.getSelectionNodes();
for (var i = nodes.length - 1; i >= 0; i--) {
if (PlacesUtils.nodeIsReadOnly(nodes[i].parent))
nodes.splice(i, 1);
}
return nodes;
return this.getSelectionNodes();
]]></body>
</method>
@ -442,36 +413,16 @@
<property name="selectedNode">
<getter><![CDATA[
var view = this.view;
var selection = view.selection;
var rc = selection.getRangeCount();
if (rc != 1)
if (view.selection.count != 1)
return null;
var selection = view.selection;
var min = { }, max = { };
selection.getRangeAt(0, min, max);
return this.getResultView().nodeForTreeIndex(min.value);
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="selectedURINode">
<getter><![CDATA[
var view = this.view;
var selection = view.selection;
var rc = selection.getRangeCount();
if (rc != 1)
return null;
var min = { }, max = { };
selection.getRangeAt(0, min, max);
// only URI nodes should be returned
var node = this.getResultView().nodeForTreeIndex(min.value);
if (PlacesUtils.nodeIsURI(node))
return node;
return null;
]]></getter>
</property>
<!-- nsIPlacesView -->
<property name="insertionPoint">
@ -526,7 +477,7 @@
// into it even if it is not opened
var itemId =
PlacesUtils.getConcreteItemId(resultView.nodeForTreeIndex(max.value));
if (this.hasSingleSelection && resultView.isContainer(max.value) &&
if (selection.count == 1 && resultView.isContainer(max.value) &&
(resultView.isContainerOpen(max.value) ||
itemId == PlacesUtils.bookmarksMenuFolderId))
orientation = Ci.nsITreeView.DROP_ON;

View File

@ -85,6 +85,13 @@ PlacesTreeView.prototype = {
if (this._tree && this._result)
this.sortingChanged(this._result.sortingMode);
var qoInt = Ci.nsINavHistoryQueryOptions;
var options = asQuery(this._result.root).queryOptions;
this._showQueryAsFolder = (options &&
(options.resultType == qoInt.RESULTS_AS_DATE_QUERY ||
options.resultType == qoInt.RESULTS_AS_SITE_QUERY ||
options.resultType == qoInt.RESULTS_AS_DATE_SITE_QUERY));
// if there is no tree, BuildVisibleList will clear everything for us
this._buildVisibleList();
},
@ -109,14 +116,6 @@ PlacesTreeView.prototype = {
sortType != nsINavHistoryQueryOptions::SORT_BY_DATE_DESCENDING)
return; // not date sorting
// showing sessions only makes sense if we are grouping by date
// any other grouping (or recursive grouping) doesn't make sense
var groupings = options.getGroupingMode({});
for (var i=0; i < groupings.length; i++) {
if (groupings[i] != Ci.nsINavHistoryQueryOptions.GROUP_BY_DAY)
return; // non-time-based grouping
}
this._showSessions = true;
},
@ -200,26 +199,6 @@ PlacesTreeView.prototype = {
var curChild = aContainer.getChild(i);
var curChildType = curChild.type;
// collapse all duplicates starting from here
if (this._collapseDuplicates) {
var showThis = { value: false };
while (i < cc - 1 &&
this._canCollapseDuplicates(curChild, aContainer.getChild(i+1),
showThis)) {
if (showThis.value) {
// collapse the first and use the second
curChild.viewIndex = -1;
curChild = aContainer.getChild(i+1);
curChildType = curChild.type;
}
else {
// collapse the second and use the first
aContainer.getChild(i+1).viewIndex = -1;
}
i++;
}
}
// don't display separators when sorted
if (curChildType == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
if (this._result.sortingMode !=
@ -418,30 +397,6 @@ PlacesTreeView.prototype = {
}
},
/**
* This returns true if the two results can be collapsed as duplicates.
* aShowThisOne will be either 0 or 1, indicating which of the
* duplicates should be shown.
*/
_canCollapseDuplicates:
function PTV__canCollapseDuplicate(aTop, aNext, aShowThisOne) {
if (!this._collapseDuplicates)
return false;
if (!PlacesUtils.nodeIsVisit(aTop) ||
!PlacesUtils.nodeIsVisit(aNext))
return false; // only collapse two visits
asVisit(aTop);
asVisit(aNext);
if (aTop.uri != aNext.uri)
return false; // don't collapse nonmatching URIs
// now we know we want to collapse, show the one with the more recent time
aShowThisOne.value = aTop.time < aNext.time;
return true;
},
_convertPRTimeToString: function PTV__convertPRTimeToString(aTime) {
var timeInMilliseconds = aTime / 1000; // PRTime is in microseconds
var timeObj = new Date(timeInMilliseconds);
@ -600,44 +555,6 @@ PlacesTreeView.prototype = {
}
}
// Try collapsing with the previous node. Note that we do not have to try
// to redraw the surrounding rows (which we normally would because session
// boundaries may have changed) because when an item is merged, it will
// always be in the same session.
var showThis = { value: true };
if (newViewIndex > 0 &&
this._canCollapseDuplicates
(this._visibleElements[newViewIndex - 1], aItem, showThis)) {
if (!showThis.value) {
// new node is invisible, collapsed with previous one
aItem.viewIndex = -1;
}
else {
// new node replaces the previous
this.itemReplaced(aParent, this._visibleElements[newViewIndex - 1],
aItem, 0);
}
return;
}
// try collapsing with the next node (which is currently at the same
// index we are trying to insert at)
if (newViewIndex < this._visibleElements.length &&
this._canCollapseDuplicates(aItem, this._visibleElements[newViewIndex],
showThis)) {
if (!showThis.value) {
// new node replaces the next node
this.itemReplaced(aParent, this._visibleElements[newViewIndex], aItem,
0);
}
else {
// new node is invisible, replaced by next one
aItem.viewIndex = -1;
}
return;
}
// no collapsing, insert new item
aItem.viewIndex = newViewIndex;
this._visibleElements.splice(newViewIndex, 0, aItem);
for (var i = newViewIndex + 1;
@ -668,40 +585,14 @@ PlacesTreeView.prototype = {
// this may have been a container, in which case it has a lot of rows
var count = this._countVisibleRowsForItem(aItem);
// We really want tail recursion here, since we sometimes do another
// remove after this when duplicates are being collapsed. This loop
// emulates that.
while (true) {
if (oldViewIndex > this._visibleElements.length)
throw("Trying to remove an item with an invalid viewIndex");
if (oldViewIndex > this._visibleElements.length)
throw("Trying to remove an item with an invalid viewIndex");
this._visibleElements.splice(oldViewIndex, count);
for (var i = oldViewIndex; i < this._visibleElements.length; i++)
this._visibleElements[i].viewIndex = i;
this._visibleElements.splice(oldViewIndex, count);
for (var i = oldViewIndex; i < this._visibleElements.length; i++)
this._visibleElements[i].viewIndex = i;
this._tree.rowCountChanged(oldViewIndex, -count);
// the removal might have put two things together that should be collapsed
if (oldViewIndex > 0 &&
oldViewIndex < this._visibleElements.length) {
var showThisOne = { value: true };
if (this._canCollapseDuplicates
(this._visibleElements[oldViewIndex - 1],
this._visibleElements[oldViewIndex], showThisOne))
{
// Fake-tail-recurse to the beginning of this function to
// remove the collapsed row. Note that we need to set the
// visible index to -1 before looping because we can never
// touch the row we're removing (callers may have already
// destroyed it).
oldViewIndex = oldViewIndex - 1 + (showThisOne.value ? 1 : 0);
this._visibleElements[oldViewIndex].viewIndex = -1;
count = 1; // next time remove one row
continue;
}
}
break; // normal path: just remove once
}
this._tree.rowCountChanged(oldViewIndex, -count);
// redraw parent because twisty may have changed
if (!aParent.hasChildren)
@ -917,22 +808,6 @@ PlacesTreeView.prototype = {
return val;
},
// nsINavHistoryResultTreeViewer
get collapseDuplicates() {
return this._collapseDuplicates;
},
set collapseDuplicates(val) {
if (this._collapseDuplicates == val)
return val; // no change;
this._collapseDuplicates = val;
if (this._tree && this._result)
this.invalidateAll();
return val;
},
nodeForTreeIndex: function PTV_nodeForTreeIndex(aIndex) {
if (aIndex > this._visibleElements.length)
throw Cr.NS_ERROR_INVALID_ARG;
@ -1007,10 +882,12 @@ PlacesTreeView.prototype = {
var nodeType = node.type;
if (PlacesUtils.containerTypes.indexOf(nodeType) != -1) {
if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY)
if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY) {
aProperties.AppendElement(this._getAtomFor("query"));
else if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
if (this._showQueryAsFolder)
aProperties.AppendElement(this._getAtomFor("folder"));
} else if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER ||
nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT) {
if (PlacesUtils.annotations.itemHasAnnotation(node.itemId,
LMANNO_FEEDURI))
aProperties.AppendElement(this._getAtomFor("livemark"));
@ -1467,7 +1344,6 @@ function PlacesTreeView(aShowRoot, aFlatList, aOnOpenFlatContainer) {
this._tree = null;
this._result = null;
this._collapseDuplicates = true;
this._showSessions = false;
this._selection = null;
this._visibleElements = [];

View File

@ -349,7 +349,10 @@ var PlacesUtils = {
*/
nodeIsHost: function PU_nodeIsHost(aNode) {
NS_ASSERT(aNode, "null node");
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST;
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
aNode.parent &&
asQuery(aNode.parent).queryOptions.resultType ==
Ci.nsINavHistoryQueryOptions.RESULTS_AS_SITE_QUERY;
},
/**
@ -359,7 +362,13 @@ var PlacesUtils = {
* @returns true if the node is a day container, false otherwise
*/
nodeIsDay: function PU_nodeIsDay(aNode) {
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY;
NS_ASSERT(aNode, "null node");
var resultType;
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
aNode.parent &&
((resultType = asQuery(aNode.parent).queryOptions.resultType) ==
Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_QUERY ||
resultType == Ci.nsINavHistoryQueryOptions.RESULTS_AS_DATE_SITE_QUERY);
},
/**
@ -371,8 +380,6 @@ var PlacesUtils = {
containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT,
Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST,
Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY,
Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER],
nodeIsContainer: function PU_nodeIsContainer(aNode) {
NS_ASSERT(aNode, "null node");
@ -1666,11 +1673,8 @@ var PlacesUtils = {
// Include visible url nodes only
let child = aNode.getChild(i);
if (this.nodeIsURI(child)) {
// If the node contents is visible, add the uri only if its node is
// visible. Otherwise follow viewer's collapseDuplicates property,
// default to true
// If the node contents is visible, add the uri
if ((wasOpen && oldViewer && child.viewIndex != -1) ||
(oldViewer && !oldViewer.collapseDuplicates) ||
urls.indexOf(child.uri) == -1) {
urls.push({ uri: child.uri,
isBookmark: this.nodeIsBookmark(child) });
@ -1780,6 +1784,51 @@ var PlacesUtils = {
this._openTabset(urlsToOpen, aEvent);
},
/**
* Loads the node's URL in the appropriate tab or window or as a web
* panel given the user's preference specified by modifier keys tracked by a
* DOM mouse/key event.
* @param aNode
* An uri result node.
* @param aEvent
* The DOM mouse/key event with modifier keys set that track the
* user's preferred destination window or tab.
*/
openNodeWithEvent: function PU_openNodeWithEvent(aNode, aEvent) {
this.openNodeIn(aNode, whereToOpenLink(aEvent));
},
/**
* Loads the node's URL in the appropriate tab or window or as a
* web panel.
* see also openUILinkIn
*/
openNodeIn: function PU_openNodeIn(aNode, aWhere) {
if (aNode && PlacesUtils.nodeIsURI(aNode) &&
PlacesUtils.checkURLSecurity(aNode)) {
var isBookmark = PlacesUtils.nodeIsBookmark(aNode);
if (isBookmark)
PlacesUtils.markPageAsFollowedBookmark(aNode.uri);
else
PlacesUtils.markPageAsTyped(aNode.uri);
// Check whether the node is a bookmark which should be opened as
// a web panel
if (aWhere == "current" && isBookmark) {
if (PlacesUtils.annotations
.itemHasAnnotation(aNode.itemId, LOAD_IN_SIDEBAR_ANNO)) {
var w = getTopWin();
if (w) {
w.openWebPanel(aNode.title, aNode.uri);
return;
}
}
}
openUILinkIn(aNode.uri, aWhere);
}
},
/**
* Helper for the toolbar and menu views
*/

View File

@ -37,6 +37,9 @@
#
# ***** END LICENSE BLOCK *****
// Load DownloadUtils module for convertByteUnits
Cu.import("resource://gre/modules/DownloadUtils.jsm");
var gAdvancedPane = {
_inited: false,
@ -196,7 +199,7 @@ var gAdvancedPane = {
allowVisible : false,
prefilledHost : "",
permissionType : "offline-app",
manageCapability : Ci.nsIPermissionManager.DENY_ACTION,
manageCapability : Components.interfaces.nsIPermissionManager.DENY_ACTION,
windowTitle : bundlePreferences.getString("offlinepermissionstitle"),
introText : bundlePreferences.getString("offlinepermissionstext") };
document.documentElement.openWindow("Browser:Permissions",
@ -217,6 +220,8 @@ var gAdvancedPane = {
list.removeChild(list.firstChild);
}
var bundle = document.getElementById("bundlePreferences");
var enumerator = pm.enumerator;
while (enumerator.hasMoreElements()) {
var perm = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
@ -225,9 +230,13 @@ var gAdvancedPane = {
perm.capability != Components.interfaces.nsIPermissionManager.DENY_ACTION) {
var row = document.createElement("listitem");
row.id = "";
row.className = "listitem";
row.setAttribute("label", perm.host);
row.className = "offlineapp";
row.setAttribute("host", perm.host);
var converted = DownloadUtils.
convertByteUnits(getOfflineAppUsage(perm.host));
row.setAttribute("usage",
bundle.getFormattedString("offlineAppUsage",
converted));
list.appendChild(row);
}
}
@ -248,7 +257,7 @@ var gAdvancedPane = {
{
var list = document.getElementById("offlineAppsList");
var item = list.selectedItem;
var host = item.getAttribute("label");
var host = item.getAttribute("host");
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);

View File

@ -51,3 +51,7 @@ richlistitem[selected="true"] {
display: -moz-box;
min-width: 16px;
}
listitem.offlineapp {
-moz-binding: url("chrome://browser/content/preferences/handlers.xml#offlineapp");
}

View File

@ -100,4 +100,14 @@
</binding>
<binding id="offlineapp"
extends="chrome://global/content/bindings/listbox.xml#listitem">
<content>
<children>
<xul:listcell xbl:inherits="label=host"/>
<xul:listcell xbl:inherits="label=usage"/>
</children>
</content>
</binding>
</bindings>

View File

@ -197,7 +197,7 @@ var gPrivacyPane = {
writeAcceptCookies: function ()
{
var checkbox = document.getElementById("acceptCookies");
return checkbox.checked ? 1 : 2;
return checkbox.checked ? 0 : 2;
},
/**

View File

@ -69,8 +69,8 @@ var SelectBookmarkDialog = {
onItemDblClick: function SBD_onItemDblClick() {
var bookmarks = document.getElementById("bookmarks");
if (bookmarks.hasSingleSelection &&
PlacesUtils.nodeIsURI(bookmarks.selectedNode)) {
var selectedNode = bookmarks.selectedNode;
if (selectedNode && PlacesUtils.nodeIsURI(selectedNode)) {
/**
* The user has double clicked on a tree row that is a link. Take this to
* mean that they want that link to be their homepage, and close the dialog.

View File

@ -43,11 +43,7 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
ifdef ENABLE_TESTS
DIRS += tests
endif
DIRS = src
ifneq (,$(BUILD_OFFICIAL)$(MOZILLA_OFFICIAL))
DEFINES += -DOFFICIAL_BUILD=1

View File

@ -82,7 +82,6 @@ function PROT_Application() {
#endif
// expose some classes
this.PROT_Controller = PROT_Controller;
this.PROT_PhishingWarden = PROT_PhishingWarden;
this.PROT_MalwareWarden = PROT_MalwareWarden;
@ -93,6 +92,36 @@ function PROT_Application() {
this.wrappedJSObject = this;
}
var gInitialized = false;
PROT_Application.prototype.initialize = function() {
if (gInitialized)
return;
gInitialized = true;
var obs = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
obs.addObserver(this, "xpcom-shutdown", true);
// XXX: move table names to a pref that we originally will download
// from the provider (need to workout protocol details)
this.malwareWarden = new PROT_MalwareWarden();
this.malwareWarden.registerBlackTable("goog-malware-shavar");
this.malwareWarden.maybeToggleUpdateChecking();
this.phishWarden = new PROT_PhishingWarden();
this.phishWarden.registerBlackTable("goog-phish-shavar");
this.phishWarden.maybeToggleUpdateChecking();
}
PROT_Application.prototype.observe = function(subject, topic, data) {
switch (topic) {
case "xpcom-shutdown":
this.malwareWarden.shutdown();
this.phishWarden.shutdown();
break;
}
}
/**
* @param name String The type of url to get (either Phish or Error).
* @return String the report phishing URL (localized).
@ -121,6 +150,8 @@ PROT_Application.prototype.getURIFlags = function(uri) {
PROT_Application.prototype.QueryInterface = function(iid) {
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsISupportsWeakReference) ||
iid.equals(Ci.nsIObserver) ||
iid.equals(Ci.nsIAboutModule))
return this;

View File

@ -1,590 +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 Google Safe Browsing.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Fritz Schneider <fritz@google.com> (original author)
#
# 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 *****
// There is one BrowserView per browser window, and each BrowserView
// is responsible for keeping track of problems (phishy documents)
// within that window. The BrowserView is also responsible for
// figuring out what to do about such problems, for example, whether
// the tab with a phishy page is currently showing and therefore if we
// should be showing a warning.
//
// The BrowserView receives information from three places:
//
// - from the phishing warden. When the phishing warden notices a
// problem, it queries all browser views to see which one (if any)
// has the Document that is problematic. It then hands the problem
// off to the appropriate BrowserView.
//
// - from the controller. The controller responds to explicit user
// actions (tab switches, requests to hide the warning message,
// etc.) and let's the BrowserView know about any user action
// having to do with the problems it is tracking.
//
// The BrowserView associates at most one "problem" with each Document
// in the browser window. It keeps state about which Documents are
// problematic by storing a "problem queue" on each browser (tab).
// At most one problematic document per browser (tab) is active
// at any time. That is, we show the warning for at most one phishy
// document at any one time. If another phishy doc loads in that tab,
// it goes onto the end of the queue to be activated only when the
// currently active document goes away.
//
// If we had multiple types of warnings (one for after the page had
// loaded, one for when the user clicked a link, etc) here's where
// we'd select the appropate one to use. As it stands, we only have
// one displayer (an "afterload" displayer). A displayer knows _how_
// to display a warning, whereas as the BrowserView knows _what_ and
// _when_.
//
// To keep things (relatively) easy to reason about and efficient (the
// phishwarden could be querying us inside a progresslistener
// notification, or the controller inside an event handler), we have
// the following rules:
//
// - at most one of a displayer's start() or stop() methods is called
// in any iteration (if calling two is required, the second is run in
// the next event loop)
// - displayers should run their operations synchronously so we don't have
// to look two places (here and in the displayer) to see what is happening
// when
// - displayer actions are run after cleaning up the browser view state
// in case they have consequences
//
// TODO: this could use some redesign, but I don't have time.
// TODO: the queue needs to be abstracted, but we want another release fast,
// so I'm not going to touch it for the time being
// TODO: IDN issues and canonical URLs?
// TODO: Perhaps we should blur the page before showing a warning in order
// to prevent stray keystrokes?
/**
* The BrowerView is responsible for keeping track of and figuring out
* what to do with problems within a single browser window.
*
* TODO
* Unify all browser-related state here. Currently it's split
* between two objects, this object and the controller. We could have
* this object be solely responsible for UI hide/show decisions, which
* would probably make it easier to reason about what's going on.
*
* TODO
* Investigate an alternative model. For example, we could factor out
* the problem signaling stuff from the tab/UI logic into a
* ProblemRegistry. Attach listeners to new docs/requests as they go
* by and have these listeners periodically check in with a
* ProblemRegistry to see if they're watching a problematic
* doc/request. If so, then have them flag the browser view to be
* aware of the problem.
*
* @constructor
* @param tabBrowser Reference to the main tabbrowser we'll use to query
* for information about active tabs/browsers.
*/
function PROT_BrowserView(tabBrowser) {
this.debugZone = "browserview";
this.tabBrowser_ = tabBrowser;
this.doc_ = this.tabBrowser_.ownerDocument;
}
/**
* Invoked by the warden to give us the opportunity to handle a
* problem. A problem is signaled once per request for a problem
* Document and is handled at most once, so there's no issue with us
* "losing" a problem due to multiple concurrently loading Documents
* with the same URL.
*
* @param warden Reference to the warden signalling the problem. We'll
* need him to instantiate one of his warning displayers
*
* @param request The nsIRequest that is problematic
*
* @returns Boolean indicating whether we handled problem
*/
PROT_BrowserView.prototype.tryToHandleProblemRequest = function(warden,
request) {
// XXX: pass around the URL instead of the request. request.name isn't
// really supposed to be used and isn't guaranteed to give the URL.
var url = request.name;
var browsers = this.tabBrowser_.browsers;
for (var i = 0; i < browsers.length; i++) {
var browser = browsers[i];
var doc = browser.contentDocument;
// We only care about top level documents (and not about frames)
if (doc.location.href == url && !this.getProblem_(doc, browser)) {
this.isProblemDocument_(browser, doc, warden);
return true;
}
}
return false;
}
/**
* We're sure a particular Document is problematic, so let's instantiate
* a dispalyer for it and add it to the problem queue for the browser.
*
* @param browser Reference to the browser in which the problem doc resides
*
* @param doc Reference to the problematic document
*
* @param warden Reference to the warden signalling the problem.
*/
PROT_BrowserView.prototype.isProblemDocument_ = function(browser,
doc,
warden) {
G_Debug(this, "Document is problem: " + doc.location.href);
var url = doc.location.href;
// We only have one type of displayer right now
var displayer = new warden.displayers_["afterload"]("Phishing afterload",
browser,
this.doc_,
url);
// We listen for the problematic document being navigated away from
// so we can remove it from the problem queue
var hideHandler = BindToObject(this.onNavAwayFromProblem_,
this,
doc,
browser);
doc.defaultView.addEventListener("pagehide", hideHandler, true);
// More info than we technically need, but it comes in handy for debugging
var problem = {
"browser_": browser,
"doc_": doc,
"displayer_": displayer,
"url_": url,
"hideHandler_": hideHandler,
};
var numInQueue = this.queueProblem_(browser, problem);
// If the queue was empty, schedule us to take something out
if (numInQueue == 1)
new G_Alarm(BindToObject(this.unqueueNextProblem_, this, browser), 0);
}
/**
* Invoked when a problematic document is navigated away from.
*
* @param doc Reference to the problematic Document navigated away from
* @param browser Reference to the browser in which the problem document
* unloaded
*/
PROT_BrowserView.prototype.onNavAwayFromProblem_ = function(doc, browser) {
var problem = this.getProblem_(doc, browser);
// We want to know if the user navigated away from the phish site
// before or after viewing the warning.
var message = problem.displayer_.messageShowing_ ? "phishnavaway"
: "ignorenavaway";
G_Debug(this, "User nav'd away from problem: " + message);
(new PROT_Reporter).report(message, problem.url_);
G_Assert(this, doc === problem.doc_, "State doc not equal to nav away doc?");
G_Assert(this, browser === problem.browser_,
"State browser not equal to nav away browser?");
this.problemResolved(browser, doc);
}
/**
* @param browser Reference to a browser we'd like to know about
*
* @returns Boolean indicating if the browser in question has
* problematic content
*/
PROT_BrowserView.prototype.hasProblem = function(browser) {
return this.hasNonemptyProblemQueue_(browser);
}
/**
* @param browser Reference to a browser we'd like to know about
*
* @returns Boolean indicating if the browser in question has a
* problem (i.e., it has a non-empty problem queue)
*/
PROT_BrowserView.prototype.hasNonemptyProblemQueue_ = function(browser) {
try {
return !!browser.PROT_problemState__ &&
!!browser.PROT_problemState__.length;
} catch(e) {
// We could be checking a browser that has just been closed, in
// which case its properties will not be valid, causing the above
// statement to throw an error. Since this case handled elsewhere,
// just return false.
return false;
}
}
/**
* Invoked to indicate that the problem for a particular problematic
* document in a browser has been resolved (e.g., by being navigated
* away from).
*
* @param browser Reference to the browser in which resolution is happening
*
* @param opt_doc Reference to the problematic doc whose problem was resolved
* (if absent, assumes the doc assocaited with the currently
* active displayer)
*/
PROT_BrowserView.prototype.problemResolved = function(browser, opt_doc) {
var problem;
var doc;
if (!!opt_doc) {
doc = opt_doc;
problem = this.getProblem_(doc, browser);
} else {
problem = this.getCurrentProblem_(browser);
doc = problem.doc_;
}
problem.displayer_.done();
var wasHead = this.deleteProblemFromQueue_(doc, browser);
// Peek at the next problem (if any) in the queue for this browser
var queueNotEmpty = this.getCurrentProblem_(browser);
if (wasHead && queueNotEmpty) {
G_Debug(this, "More problems pending. Scheduling unqueue.");
new G_Alarm(BindToObject(this.unqueueNextProblem_, this, browser), 0);
}
}
/**
* Peek at the top of the problem queue and if there's something there,
* make it active.
*
* @param browser Reference to the browser we should activate a problem
* displayer in if one is available
*/
PROT_BrowserView.prototype.unqueueNextProblem_ = function(browser) {
var problem = this.getCurrentProblem_(browser);
if (!problem) {
G_Debug(this, "No problem in queue; doc nav'd away from? (shrug)");
return;
}
// Two problem docs that load in rapid succession could both schedule
// themselves to be unqueued before this method is called. So ensure
// that the problem at the head of the queue is not, in fact, active.
if (!problem.displayer_.isActive()) {
// It could be the case that the server is really slow to respond,
// so there might not yet be anything in the problem Document. If
// we show the warning when that's the case, the user will see a
// blank document greyed out, and if they cancel the dialog
// they'll see the page they're navigating away from because it
// hasn't been painted over yet (b/c there's no content for the
// problem page). So here we ensure that we have content for the
// problem page before showing the dialog.
var haveContent = false;
try {
// This will throw if there's no content yet
var h = problem.doc_.defaultView.getComputedStyle(problem.doc_.body, "")
.getPropertyValue("height");
G_Debug(this, "body height: " + h);
if (Number(h.substring(0, h.length - 2)))
haveContent = true;
} catch (e) {
G_Debug(this, "Masked in unqueuenextproblem: " + e);
}
if (!haveContent) {
G_Debug(this, "Didn't get computed style. Re-queueing.");
// One stuck problem document in a page shouldn't prevent us
// warning on other problem frames that might be loading or
// loaded. So stick the Document that doesn't have content
// back at the end of the queue.
var p = this.removeProblemFromQueue_(problem.doc_, browser);
G_Assert(this, p === problem, "Unqueued wrong problem?");
this.queueProblem_(browser, problem);
// Try again in a bit. This opens us up to a potential
// vulnerability (put tons of hanging frames in a page
// ahead of your real phishy frame), but the risk at the
// moment is really low (plus it is outside our threat
// model).
new G_Alarm(BindToObject(this.unqueueNextProblem_,
this,
browser),
200 /*ms*/);
return;
}
problem.displayer_.start();
// OK, we have content, but there there is an additional
// issue. Due to a bfcache bug, if we show the warning during
// paint suppression, the collapsing of the content pane affects
// the doc we're naving from :( The symptom is a page with grey
// screen on navigation to or from a phishing page (the
// contentDocument will have width zero).
//
// Paint supression lasts at most 250ms from when the parser sees
// the body, and the parser sees the body well before it has a
// height. We err on the side of caution.
//
// Thanks to bryner for helping to track the bfcache bug down.
// https://bugzilla.mozilla.org/show_bug.cgi?id=319646
if (this.tabBrowser_.selectedBrowser === browser)
new G_Alarm(BindToObject(this.problemBrowserMaybeSelected,
this,
browser),
350 /*ms*/);
}
}
/**
* Helper function that adds a new problem to the queue of problems pending
* on this browser.
*
* @param browser Browser to which we should add state
*
* @param problem Object (structure, really) encapsulating the problem
*
* @returns Number indicating the number of items in the queue (and from
* which you can infer whether the recently added item was
* placed at the head, and hence should be active.
*/
PROT_BrowserView.prototype.queueProblem_ = function(browser, problem) {
G_Debug(this, "Adding problem state for " + problem.url_);
if (this.hasNonemptyProblemQueue_(browser))
G_Debug(this, "Already has problem state. Queueing this problem...");
// First problem ever signaled on this browser? Make a new queue!
if (browser.PROT_problemState__ == undefined)
browser.PROT_problemState__ = [];
browser.PROT_problemState__.push(problem);
return browser.PROT_problemState__.length;
}
/**
* Helper function that removes a problem from the queue and deactivates
* it.
*
* @param doc Reference to the doc for which we should remove state
*
* @param browser Reference to the browser from which we should remove
* state
*
* @returns Boolean indicating if the remove problem was currently active
* (that is, if it was at the head of the queue)
*/
PROT_BrowserView.prototype.deleteProblemFromQueue_ = function(doc, browser) {
G_Debug(this, "Deleting problem state for " + browser);
G_Assert(this, !!this.hasNonemptyProblemQueue_(browser),
"Browser has no problem state");
var problem = this.getProblem_(doc, browser);
G_Assert(this, !!problem, "Couldnt find state in removeproblemstate???");
var wasHead = browser.PROT_problemState__[0] === problem;
this.removeProblemFromQueue_(doc, browser);
var hideHandler = problem.hideHandler_;
G_Assert(this, !!hideHandler, "No hidehandler in state?");
problem.doc_.defaultView.removeEventListener("pagehide",
hideHandler,
true);
return wasHead;
}
/**
* Helper function that removes a problem from the queue but does
* NOT deactivate it.
*
* @param doc Reference to the doc for which we should remove state
*
* @param browser Reference to the browser from which we should remove
* state
*
* @returns Boolean indicating if the remove problem was currently active
* (that is, if it was at the head of the queue)
*/
PROT_BrowserView.prototype.removeProblemFromQueue_ = function(doc, browser) {
G_Debug(this, "Removing problem state for " + browser);
G_Assert(this, !!this.hasNonemptyProblemQueue_(browser),
"Browser has no problem state");
var problem = null;
// TODO Blech. Let's please have an abstraction here instead.
for (var i = 0; i < browser.PROT_problemState__.length; i++)
if (browser.PROT_problemState__[i].doc_ === doc) {
problem = browser.PROT_problemState__.splice(i, 1)[0];
break;
}
return problem;
}
/**
* Retrieve (but do not remove) the problem state for a particular
* problematic Document in this browser
*
* @param doc Reference to the problematic doc to get state for
*
* @param browser Reference to the browser from which to get state
*
* @returns Object encapsulating the state we stored, or null if none
*/
PROT_BrowserView.prototype.getProblem_ = function(doc, browser) {
if (!this.hasNonemptyProblemQueue_(browser))
return null;
// TODO Blech. Let's please have an abstraction here instead.
for (var i = 0; i < browser.PROT_problemState__.length; i++)
if (browser.PROT_problemState__[i].doc_ === doc)
return browser.PROT_problemState__[i];
return null;
}
/**
* Retrieve the problem state for the currently active problem Document
* in this browser
*
* @param browser Reference to the browser from which to get state
*
* @returns Object encapsulating the state we stored, or null if none
*/
PROT_BrowserView.prototype.getCurrentProblem_ = function(browser) {
return browser.PROT_problemState__[0];
}
/**
* Invoked by the controller when the user switches tabs away from a problem
* tab.
*
* @param browser Reference to the tab that was switched from
*/
PROT_BrowserView.prototype.problemBrowserUnselected = function(browser) {
var problem = this.getCurrentProblem_(browser);
G_Assert(this, !!problem, "Couldn't get state from browser");
problem.displayer_.browserUnselected();
}
/**
* Checks to see if the problem browser is selected, and if so,
* tell it it to show its warning.
*
* @param browser Reference to the browser we wish to check
*/
PROT_BrowserView.prototype.problemBrowserMaybeSelected = function(browser) {
var problem = this.getCurrentProblem_(browser);
if (this.tabBrowser_.selectedBrowser === browser &&
problem &&
problem.displayer_.isActive())
this.problemBrowserSelected(browser);
}
/**
* Invoked by the controller when the user switches tabs to a problem tab
*
* @param browser Reference to the tab that was switched to
*/
PROT_BrowserView.prototype.problemBrowserSelected = function(browser) {
G_Debug(this, "Problem browser selected");
var problem = this.getCurrentProblem_(browser);
G_Assert(this, !!problem, "No state? But we're selected!");
problem.displayer_.browserSelected();
}
/**
* Invoked by the controller when the user accepts our warning. Passes
* the accept through to the message displayer, which knows what to do
* (it will be displayer-specific).
*
* @param browser Reference to the browser for which the user accepted
* our warning
*/
PROT_BrowserView.prototype.acceptAction = function(browser) {
var problem = this.getCurrentProblem_(browser);
// We run the action only after we're completely through processing
// this event. We do this because the action could cause state to be
// cleared (e.g., by navigating the problem document) that we need
// to finish processing the event.
new G_Alarm(BindToObject(problem.displayer_.acceptAction,
problem.displayer_),
0);
}
/**
* Invoked by the controller when the user declines our
* warning. Passes the decline through to the message displayer, which
* knows what to do (it will be displayer-specific).
*
* @param browser Reference to the browser for which the user declined
* our warning
*/
PROT_BrowserView.prototype.declineAction = function(browser) {
var problem = this.getCurrentProblem_(browser);
G_Assert(this, !!problem, "User declined but no state???");
// We run the action only after we're completely through processing
// this event. We do this because the action could cause state to be
// cleared (e.g., by navigating the problem document) that we need
// to finish processing the event.
new G_Alarm(BindToObject(problem.displayer_.declineAction,
problem.displayer_),
0);
}
/**
* The user wants to see the warning message. So let em! At some point when
* we have multiple types of warnings, we'll have to mediate them here.
*
* @param browser Reference to the browser that has the warning the user
* wants to see.
*/
PROT_BrowserView.prototype.explicitShow = function(browser) {
var problem = this.getCurrentProblem_(browser);
G_Assert(this, !!problem, "Explicit show on browser w/o problem state???");
problem.displayer_.explicitShow();
}

View File

@ -1,203 +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 Google Safe Browsing.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Fritz Schneider <fritz@google.com> (original author)
# Simon Bünzli <zeniko@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
// This is our controller -- the thingy that listens to what the user
// is doing. There is one controller per browser window, and each has
// a BrowserView that manages information about problems within the
// window. The controller figures out when the browser might want to
// know about something, but the browser view figures out what exactly
// to do (and the BrowserView's displayer figures out how to do it).
//
// For example, the controller might notice that the user has switched
// to a tab that has something problematic in it. It would tell its
// BrowserView this, and the BrowserView would figure out whether it
// is appropriate to show a warning (e.g., perhaps the user previously
// dismissed the warning for that problem). If so, the BrowserView tells
// the displayer to show the warning. Anyhoo...
//
// TODO Could move all browser-related hide/show logic into the browser
// view. Need to think about this more.
/**
* Handles user actions, translating them into messages to the view
*
* @constructor
* @param win Reference to the Window (browser window context) we should
* attach to
* @param tabBrowser Reference to the window's main tabbrowser object.
* @param phishingWarden Reference to the PhishingWarden we should register
* our browserview with
*/
function PROT_Controller(win, tabBrowser, phishingWarden) {
this.debugZone = "controller";
this.win_ = win;
this.phishingWarden_ = phishingWarden;
// Use this to query preferences
this.prefs_ = new G_Preferences();
// Set us up to receive the events we want.
this.tabBrowser_ = tabBrowser;
this.onTabSwitchClosure_ = BindToObject(this.onTabSwitch, this);
this.tabBrowser_.mTabBox.addEventListener("select", this.onTabSwitchClosure_, true);
// Used to determine when the user has switched tabs
this.lastTab_ = tabBrowser.selectedBrowser;
// Install our command controllers. These commands are issued from
// various places in our UI, including our preferences dialog, the
// warning dialog, etc.
var commandHandlers = {
"safebrowsing-show-warning" :
BindToObject(this.onUserShowWarning, this),
"safebrowsing-accept-warning" :
BindToObject(this.onUserAcceptWarning, this),
"safebrowsing-decline-warning" :
BindToObject(this.onUserDeclineWarning, this),
};
this.commandController_ = new PROT_CommandController(commandHandlers);
this.win_.controllers.appendController(this.commandController_);
// This guy embodies the logic of when to display warnings
// (displayers embody the how).
this.browserView_ = new PROT_BrowserView(this.tabBrowser_);
G_Debug(this, "Controller initialized.");
}
/**
* Invoked when the browser window is closing. Do some cleanup.
*/
PROT_Controller.prototype.shutdown = function(e) {
G_Debug(this, "Browser window closing. Shutting controller down.");
if (this.commandController_) {
this.win_.controllers.removeController(this.commandController_);
this.commandController_ = null;
}
// No need to drain the browser view's problem queue explicitly; it will
// receive pagehides for all the browsers in its queues as they're torn
// down, and it will remove them.
this.browserView_ = null;
if (this.tabBrowser_)
this.tabBrowser_.mTabBox.removeEventListener("select", this.onTabSwitchClosure_, true);
// Break circular refs so we can be gc'ed.
this.tabBrowser_ = this.lastTab_ = null;
this.win_.removeEventListener("unload", this.onShutdown_, false);
this.prefs_ = null;
G_Debug(this, "Controller shut down.");
}
/**
* The user clicked the urlbar icon; they want to see the warning message
* again.
*/
PROT_Controller.prototype.onUserShowWarning = function() {
var browser = this.tabBrowser_.selectedBrowser;
this.browserView_.explicitShow(browser);
}
/**
* Deal with a user accepting our warning.
*
* TODO the warning hide/display instructions here can probably be moved
* into the browserview in the future, given its knowledge of when the
* problem doc hides/shows.
*/
PROT_Controller.prototype.onUserAcceptWarning = function() {
G_Debug(this, "User accepted warning.");
var browser = this.tabBrowser_.selectedBrowser;
G_Assert(this, !!browser, "Couldn't get current browser?!?");
G_Assert(this, this.browserView_.hasProblem(browser),
"User accept fired, but browser doesn't have warning showing?!?");
this.browserView_.acceptAction(browser);
this.browserView_.problemResolved(browser);
}
/**
* Deal with a user declining our warning.
*
* TODO the warning hide/display instructions here can probably be moved
* into the browserview in the future, given its knowledge of when the
* problem doc hides/shows.
*/
PROT_Controller.prototype.onUserDeclineWarning = function() {
G_Debug(this, "User declined warning.");
var browser = this.tabBrowser_.selectedBrowser;
G_Assert(this, this.browserView_.hasProblem(browser),
"User decline fired, but browser doesn't have warning showing?!?");
this.browserView_.declineAction(browser);
// We don't call problemResolved() here because all declining does it
// hide the message; we still have the urlbar icon showing, giving
// the user the ability to bring the warning message back up if they
// so desire.
}
/**
* Notice tab switches, and display or hide warnings as appropriate.
*
* TODO this logic can probably move into the browser view at some
* point. But one thing at a time.
*/
PROT_Controller.prototype.onTabSwitch = function(e) {
// Filter spurious events
// The event target is usually tabs but can be tabpanels when tabs were opened
// programatically via tabbrowser.addTab().
if (!e.target || (e.target.localName != "tabs" && e.target.localName != "tabpanels"))
return;
var fromBrowser = this.lastTab_;
var toBrowser = this.tabBrowser_.selectedBrowser;
if (fromBrowser != toBrowser) {
this.lastTab_ = toBrowser;
if (this.browserView_.hasProblem(fromBrowser))
this.browserView_.problemBrowserUnselected(fromBrowser);
if (this.browserView_.hasProblem(toBrowser))
this.browserView_.problemBrowserSelected(toBrowser);
}
}

View File

@ -1,83 +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 Google Safe Browsing.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Fritz Schneider <fritz@google.com> (original author)
#
# 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 *****
// Some misc command-related plumbing used by the controller.
/**
* A tiny wrapper class for super-simple command handlers.
*
* @param commandHandlerMap An object containing name/value pairs where
* the name is command name (string) and value
* is the function to execute for that command
*/
function PROT_CommandController(commandHandlerMap) {
this.debugZone = "commandhandler";
this.cmds_ = commandHandlerMap;
}
/**
* @param cmd Command to query support for
* @returns Boolean indicating if this controller supports cmd
*/
PROT_CommandController.prototype.supportsCommand = function(cmd) {
return (cmd in this.cmds_);
}
/**
* Trivial implementation
*
* @param cmd Command to query status of
*/
PROT_CommandController.prototype.isCommandEnabled = function(cmd) {
return true;
}
/**
* Execute a command
*
* @param cmd Command to execute
*/
PROT_CommandController.prototype.doCommand = function(cmd) {
return this.cmds_[cmd]();
}
/**
* Trivial implementation
*/
PROT_CommandController.prototype.onEvent = function(cmd) { }

View File

@ -131,9 +131,13 @@ PROT_DataProvider.prototype.updateListManager_ = function() {
listManager.setUpdateUrl(this.getUpdateURL());
// setKeyUrl has the side effect of fetching a key from the server.
// This shouldn't happen if anti-phishing is disabled or we're in local
// list mode, so we need to check for that.
var isEnabled = this.prefs_.getPref(kPhishWardenEnabledPref, false);
// This shouldn't happen if anti-phishing/anti-malware is disabled.
var isEnabled = this.prefs_.getPref(kPhishWardenEnabledPref, false) ||
this.prefs_.getPref(kMalwareWardenEnabledPref, false);
if (isEnabled) {
listManager.setKeyUrl(this.keyURL_);
}
listManager.setGethashUrl(this.getGethashURL());
}

View File

@ -18,8 +18,7 @@
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Niels Provos <niels@google.com> (original author)d
# Niels Provos <niels@google.com> (original author)
# Fritz Schneider <fritz@google.com>
#
# Alternatively, the contents of this file may be used under the terms of

View File

@ -89,8 +89,8 @@ function PROT_MalwareWarden() {
};
try {
dbService_.beginUpdate(listener);
dbService_.beginStream("");
dbService_.beginUpdate(listener, "");
dbService_.beginStream("", "");
dbService_.updateStream(testUpdate);
dbService_.finishStream();
dbService_.finishUpdate();

View File

@ -1,716 +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 Google Safe Browsing.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Fritz Schneider <fritz@google.com> (original author)
#
# 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 *****
// Implementation of the warning message we show users when we
// notice navigation to a phishing page after it has loaded. The
// browser view encapsulates all the hide/show logic, so the displayer
// doesn't need to know when to display itself, only how.
//
// Displayers implement the following interface:
//
// start() -- fired to initialize the displayer (to make it active). When
// called, this displayer starts listening for and responding to
// events. At most one displayer per tab should be active at a
// time, and start() should be called at most once.
// declineAction() -- fired when the user declines the warning.
// acceptAction() -- fired when the user declines the warning
// explicitShow() -- fired when the user wants to see the warning again
// browserSelected() -- the browser is the top tab
// browserUnselected() -- the browser is no long the top tab
// done() -- clean up. May be called once (even if the displayer wasn't
// activated).
//
// At the moment, all displayers share access to the same xul in
// safebrowsing-overlay.xul. Hence the need for at most one displayer
// to be active per tab at a time.
/**
* Factory that knows how to create a displayer appropriate to the
* user's platform. We use a clunky canvas-based displayer for all
* platforms until such time as we can overlay semi-transparent
* areas over browser content.
*
* See the base object for a description of the constructor args
*
* @constructor
*/
function PROT_PhishMsgDisplayer(msgDesc, browser, doc, url) {
// TODO: Change this to return a PhishMsgDisplayerTransp on windows
// (and maybe other platforms) when Firefox 2.0 hits.
return new PROT_PhishMsgDisplayerCanvas(msgDesc, browser, doc, url);
}
/**
* Base class that implements most of the plumbing required to hide
* and show a phishing warning. Subclasses implement the actual
* showMessage and hideMessage methods.
*
* This class is not meant to be instantiated directly.
*
* @param msgDesc String describing the kind of warning this is
* @param browser Reference to the browser over which we display the msg
* @param doc Reference to the document in which browser is found
* @param url String containing url of the problem document
* @constructor
*/
function PROT_PhishMsgDisplayerBase(msgDesc, browser, doc, url) {
this.debugZone = "phishdisplayer";
this.msgDesc_ = msgDesc; // currently unused
this.browser_ = browser;
this.doc_ = doc;
this.url_ = url;
// We'll need to manipulate the XUL in safebrowsing-overlay.xul
this.messageId_ = "safebrowsing-palm-message";
this.messageTailId_ = "safebrowsing-palm-message-tail-container";
this.messageContentId_ = "safebrowsing-palm-message-content";
this.extendedMessageId_ = "safebrowsing-palm-extended-message";
this.showmoreLinkId_ = "safebrowsing-palm-showmore-link";
this.faqLinkId_ = "safebrowsing-palm-faq-link";
this.urlbarIconId_ = "safebrowsing-urlbar-icon";
this.refElementId_ = this.urlbarIconId_;
// We use this to report user actions to the server
this.reporter_ = new PROT_Reporter();
// The active UI elements in our warning send these commands; bind them
// to their handlers but don't register the commands until we start
// (because another displayer might be active)
this.commandHandlers_ = {
"safebrowsing-palm-showmore":
BindToObject(this.showMore_, this),
};
this.windowWatcher_ =
Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
}
/**
* @returns The default background color of the browser
*/
PROT_PhishMsgDisplayerBase.prototype.getBackgroundColor_ = function() {
var pref = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
return pref.getCharPref("browser.display.background_color");
}
/**
* Fired when the user declines our warning. Report it!
*/
PROT_PhishMsgDisplayerBase.prototype.declineAction = function() {
G_Debug(this, "User declined warning.");
G_Assert(this, this.started_, "Decline on a non-active displayer?");
this.reporter_.report("phishdecline", this.url_);
this.messageShouldShow_ = false;
if (this.messageShowing_)
this.hideMessage_();
}
/**
* Fired when the user accepts our warning
*/
PROT_PhishMsgDisplayerBase.prototype.acceptAction = function() {
G_Assert(this, this.started_, "Accept on an unstarted displayer?");
G_Assert(this, this.done_, "Accept on a finished displayer?");
G_Debug(this, "User accepted warning.");
this.reporter_.report("phishaccept", this.url_);
var url = this.getMeOutOfHereUrl_();
this.browser_.loadURI(url);
}
/**
* Get the url for "Get me out of here." This is the browser's default home
* page, or, about:blank.
* @return String url
*/
PROT_PhishMsgDisplayerBase.prototype.getMeOutOfHereUrl_ = function() {
// Try to get their homepage from prefs.
var prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService).getDefaultBranch(null);
var url = "about:blank";
try {
url = prefs.getComplexValue("browser.startup.homepage",
Ci.nsIPrefLocalizedString).data;
// If url is a pipe-delimited set of pages, just take the first one.
// This will need to change once bug 221445 is fixed.
if (url.indexOf("|") != -1)
url = url.split("|")[0];
} catch(e) {
G_Debug(this, "Couldn't get homepage pref: " + e);
}
return url;
}
/**
* Invoked when the browser is resized
*/
PROT_PhishMsgDisplayerBase.prototype.onBrowserResized_ = function(event) {
G_Debug(this, "Got resize for " + event.target);
if (this.messageShowing_) {
this.hideMessage_();
this.showMessage_();
}
}
/**
* Invoked by the browser view when our browser is switched to
*/
PROT_PhishMsgDisplayerBase.prototype.browserSelected = function() {
G_Assert(this, this.started_, "Displayer selected before being started???");
// If messageshowing hasn't been set, then this is the first time this
// problematic browser tab has been on top, so do our setup and show
// the warning.
if (this.messageShowing_ === undefined) {
this.messageShouldShow_ = true;
}
this.addWarningInUrlbar_(); // Goes away when we are unselected or unloaded
// messageShouldShow might be false if the user dismissed the warning,
// switched tabs, and then switched back. We're still active, but don't
// want to show the warning again. The user can cause it to show by
// clicking our icon in the urlbar.
if (this.messageShouldShow_)
this.showMessage_();
}
/**
* Invoked to display the warning message explicitly, for example if the user
* clicked the url warning icon.
*/
PROT_PhishMsgDisplayerBase.prototype.explicitShow = function() {
this.messageShouldShow_ = true;
if (!this.messageShowing_)
this.showMessage_();
}
/**
* Invoked by the browser view when our browser is switched away from
*/
PROT_PhishMsgDisplayerBase.prototype.browserUnselected = function() {
this.removeWarningInUrlbar_();
if (this.messageShowing_)
this.hideMessage_();
}
/**
* Invoked to make this displayer active. The displayer will now start
* responding to notifications such as commands and resize events. We
* can't do this in the constructor because there might be many
* displayers instantiated waiting in the problem queue for a particular
* browser (e.g., a page has multiple framed problem pages), and we
* don't want them all responding to commands!
*
* Invoked zero (the page we're a warning for was nav'd away from
* before it reaches the head of the problem queue) or one (we're
* displaying this warning) times by the browser view.
*/
PROT_PhishMsgDisplayerBase.prototype.start = function() {
G_Assert(this, this.started_ == undefined, "Displayer started twice?");
this.started_ = true;
this.commandController_ = new PROT_CommandController(this.commandHandlers_);
this.doc_.defaultView.controllers.appendController(this.commandController_);
// Add an event listener for when the browser resizes (e.g., user
// shows/hides the sidebar).
this.resizeHandler_ = BindToObject(this.onBrowserResized_, this);
this.browser_.addEventListener("resize",
this.resizeHandler_,
false);
}
/**
* @returns Boolean indicating whether this displayer is currently
* active
*/
PROT_PhishMsgDisplayerBase.prototype.isActive = function() {
return !!this.started_;
}
/**
* Invoked by the browser view to clean up after the user is done
* interacting with the message. Should be called once by the browser
* view.
*/
PROT_PhishMsgDisplayerBase.prototype.done = function() {
G_Assert(this, !this.done_, "Called done more than once?");
this.done_ = true;
// If the Document we're showing the warning for was nav'd away from
// before we had a chance to get started, we have nothing to do.
if (this.started_) {
// If we were started, we must be the current problem, so these things
// must be showing
this.removeWarningInUrlbar_();
// Could be though that they've closed the warning dialog
if (this.messageShowing_)
this.hideMessage_();
if (this.resizeHandler_) {
this.browser_.removeEventListener("resize",
this.resizeHandler_,
false);
this.resizeHandler_ = null;
}
var win = this.doc_.defaultView;
win.controllers.removeController(this.commandController_);
this.commandController_ = null;
}
}
/**
* Helper function to remove a substring from inside a string.
*
* @param orig String to remove substring from
*
* @param toRemove String to remove (if it is present)
*
* @returns String with the substring removed
*/
PROT_PhishMsgDisplayerBase.prototype.removeIfExists_ = function(orig,
toRemove) {
var pos = orig.indexOf(toRemove);
if (pos != -1)
orig = orig.substring(0, pos) + orig.substring(pos + toRemove.length);
return orig;
}
/**
* This method makes our warning icon visible in the location bar. It will
* be removed only when the problematic document is navigated awy from
* (i.e., when done() is called), and not when the warning is dismissed.
*/
PROT_PhishMsgDisplayerBase.prototype.addWarningInUrlbar_ = function() {
var urlbarIcon = this.doc_.getElementById(this.urlbarIconId_);
if (!urlbarIcon)
return;
urlbarIcon.setAttribute('level', 'warn');
}
/**
* Hides our urlbar icon
*/
PROT_PhishMsgDisplayerBase.prototype.removeWarningInUrlbar_ = function() {
var urlbarIcon = this.doc_.getElementById(this.urlbarIconId_);
if (!urlbarIcon)
return;
urlbarIcon.setAttribute('level', 'safe');
}
/**
* VIRTUAL -- Displays the warning message
*/
PROT_PhishMsgDisplayerBase.prototype.showMessage_ = function() { };
/**
* VIRTUAL -- Hide the warning message from the user.
*/
PROT_PhishMsgDisplayerBase.prototype.hideMessage_ = function() { };
/**
* Reposition the message relative to refElement in the parent window
*
* @param message Reference to the element to position
* @param tail Reference to the message tail
* @param refElement Reference to element relative to which we position
* ourselves
*/
PROT_PhishMsgDisplayerBase.prototype.adjustLocation_ = function(message,
tail,
refElement) {
var refX = refElement.boxObject.x;
var refY = refElement.boxObject.y;
var refHeight = refElement.boxObject.height;
var refWidth = refElement.boxObject.width;
G_Debug(this, "Ref element is at [window-relative] (" + refX + ", " +
refY + ")");
var pixelsIntoRefY = -2;
var tailY = refY + refHeight - pixelsIntoRefY;
var tailPixelsLeftOfRefX = tail.boxObject.width;
var tailPixelsIntoRefX = Math.round(refWidth / 2);
var tailX = refX - tailPixelsLeftOfRefX + tailPixelsIntoRefX;
// Move message up a couple pixels so the tail overlaps it.
var messageY = tailY + tail.boxObject.height - 2;
var messagePixelsLeftOfRefX = 375;
var messageX = refX - messagePixelsLeftOfRefX;
G_Debug(this, "Message is at [window-relative] (" + messageX + ", " +
messageY + ")");
G_Debug(this, "Tail is at [window-relative] (" + tailX + ", " +
tailY + ")");
if (messageX < 0) {
// We're hanging off the left edge, switch to floating mode
tail.style.display = "none";
this.adjustLocationFloating_(message);
return;
}
tail.style.top = tailY + "px";
tail.style.left = tailX + "px";
message.style.top = messageY + "px";
message.style.left = messageX + "px";
this.maybeAddScrollbars_();
}
/**
* Position the warning bubble with no reference element. In this case we
* just center the warning bubble at the top of the users window.
* @param message XULElement message bubble XUL container.
*/
PROT_PhishMsgDisplayerBase.prototype.adjustLocationFloating_ = function(message) {
// Compute X offset
var browserX = this.browser_.boxObject.x;
var browserXCenter = browserX + this.browser_.boxObject.width / 2;
var messageX = browserXCenter - (message.boxObject.width / 2);
// Compute Y offset (top of the browser window)
var messageY = this.browser_.boxObject.y;
// Position message
message.style.top = messageY + "px";
message.style.left = messageX + "px";
this.maybeAddScrollbars_();
}
/**
* Add a vertical scrollbar if we're falling out of the browser window.
*/
PROT_PhishMsgDisplayerBase.prototype.maybeAddScrollbars_ = function() {
var message = this.doc_.getElementById(this.messageId_);
var content = this.doc_.getElementById(this.messageContentId_);
var bottom = content.boxObject.y + content.boxObject.height;
var maxY = this.doc_.defaultView.innerHeight;
G_Debug(this, "bottom: " + bottom + ", maxY: " + maxY
+ ", new height: " + (maxY - content.boxObject.y));
if (bottom > maxY) {
var newHeight = maxY - content.boxObject.y;
if (newHeight < 1)
newHeight = 1;
content.style.height = newHeight + "px";
content.style.overflow = "auto";
}
}
/**
* Show the extended warning message
*/
PROT_PhishMsgDisplayerBase.prototype.showMore_ = function() {
this.doc_.getElementById(this.extendedMessageId_).hidden = false;
this.doc_.getElementById(this.showmoreLinkId_).style.display = "none";
// set FAQ URL
var formatter = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
.getService(Components.interfaces.nsIURLFormatter);
var faqURL = formatter.formatURLPref("browser.safebrowsing.warning.infoURL");
var labelEl = this.doc_.getElementById(this.faqLinkId_);
labelEl.setAttribute("href", faqURL);
this.maybeAddScrollbars_();
}
/**
* The user clicked on one of the links in the buble. Display the
* corresponding page in a new window with all the chrome enabled.
*
* @param url The URL to display in a new window
*/
PROT_PhishMsgDisplayerBase.prototype.showURL_ = function(url) {
this.windowWatcher_.openWindow(this.windowWatcher_.activeWindow,
url,
"_blank",
null,
null);
}
/**
* If the warning bubble came up in error, this url goes to a form
* to notify the data provider.
* @return url String
*/
PROT_PhishMsgDisplayerBase.prototype.getReportErrorURL_ = function() {
var badUrl = this.url_;
var url = gDataProvider.getReportErrorURL();
url += "&url=" + encodeURIComponent(badUrl);
return url;
}
/**
* URL for the user to report back to us. This is to provide the user
* with an action after being warned.
*/
PROT_PhishMsgDisplayerBase.prototype.getReportGenericURL_ = function() {
var badUrl = this.url_;
var url = gDataProvider.getReportGenericURL();
url += "&url=" + encodeURIComponent(badUrl);
return url;
}
/**
* A specific implementation of the dislpayer using a canvas. This
* class is meant for use on platforms that don't support transparent
* elements over browser content (currently: all platforms).
*
* The main ugliness is the fact that we're hiding the content area and
* painting the page to canvas. As a result, we must periodically
* re-paint the canvas to reflect updates to the page. Otherwise if
* the page was half-loaded when we showed our warning, it would
* stay that way even though the page actually finished loading.
*
* See base constructor for full details of constructor args.
*
* @constructor
*/
function PROT_PhishMsgDisplayerCanvas(msgDesc, browser, doc, url) {
PROT_PhishMsgDisplayerBase.call(this, msgDesc, browser, doc, url);
this.dimAreaId_ = "safebrowsing-dim-area-canvas";
this.pageCanvasId_ = "safebrowsing-page-canvas";
this.xhtmlNS_ = "http://www.w3.org/1999/xhtml"; // we create html:canvas
}
PROT_PhishMsgDisplayerCanvas.inherits(PROT_PhishMsgDisplayerBase);
/**
* Displays the warning message. First we make sure the overlay is loaded
* then call showMessageAfterOverlay_.
*/
PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { }
/**
* This does the actual work of showing the warning message.
*/
PROT_PhishMsgDisplayerCanvas.prototype.showMessageAfterOverlay_ = function() {
this.messageShowing_ = true;
// Position the canvas overlay. Order here is significant, but don't ask me
// why for some of these. You need to:
// 1. get browser dimensions
// 2. add canvas to the document
// 3. unhide the dimmer (gray out overlay)
// 4. display to the canvas
// 5. unhide the warning message
// 6. update link targets in warning message
// 7. focus the warning message
// (1)
var w = this.browser_.boxObject.width;
G_Debug(this, "browser w=" + w);
var h = this.browser_.boxObject.height;
G_Debug(this, "browser h=" + h);
var x = this.browser_.boxObject.x;
G_Debug(this, "browser x=" + w);
var y = this.browser_.boxObject.y;
G_Debug(this, "browser y=" + h);
var win = this.browser_.contentWindow;
var scrollX = win.scrollX;
G_Debug(this, "win scrollx=" + scrollX);
var scrollY = win.scrollY;
G_Debug(this, "win scrolly=" + scrollY);
// (2)
// We add the canvas dynamically and remove it when we're done because
// leaving it hanging around consumes a lot of memory.
var pageCanvas = this.doc_.createElementNS(this.xhtmlNS_, "html:canvas");
pageCanvas.id = this.pageCanvasId_;
pageCanvas.style.left = x + 'px';
pageCanvas.style.top = y + 'px';
var dimarea = this.doc_.getElementById(this.dimAreaId_);
this.doc_.getElementById('main-window').insertBefore(pageCanvas,
dimarea);
// (3)
dimarea.style.left = x + 'px';
dimarea.style.top = y + 'px';
dimarea.style.width = w + 'px';
dimarea.style.height = h + 'px';
dimarea.hidden = false;
// (4)
pageCanvas.setAttribute("width", w);
pageCanvas.setAttribute("height", h);
var bgcolor = this.getBackgroundColor_();
var cx = pageCanvas.getContext("2d");
cx.drawWindow(win, scrollX, scrollY, w, h, bgcolor);
// Now repaint the window every so often in case the content hasn't fully
// loaded at this point.
var debZone = this.debugZone;
function repaint() {
G_Debug(debZone, "Repainting canvas...");
cx.drawWindow(win, scrollX, scrollY, w, h, bgcolor);
};
this.repainter_ = new PROT_PhishMsgCanvasRepainter(repaint);
// (5)
this.showAndPositionWarning_();
// (6)
var link = this.doc_.getElementById('safebrowsing-palm-falsepositive-link');
link.href = this.getReportErrorURL_();
// (7)
this.doc_.getElementById(this.messageContentId_).focus();
}
/**
* Show and position the warning message. We position the waring message
* relative to the icon in the url bar, but if the element doesn't exist,
* (e.g., the user remove the url bar from her/his chrome), we anchor at the
* top of the window.
*/
PROT_PhishMsgDisplayerCanvas.prototype.showAndPositionWarning_ = function() {
var refElement = this.doc_.getElementById(this.refElementId_);
var message = this.doc_.getElementById(this.messageId_);
var tail = this.doc_.getElementById(this.messageTailId_);
message.hidden = false;
message.style.display = "block";
// Determine if the refElement is visible.
if (this.isVisibleElement_(refElement)) {
// Show tail and position warning relative to refElement.
tail.hidden = false;
tail.style.display = "block";
this.adjustLocation_(message, tail, refElement);
} else {
// No ref element, position in the top center of window.
tail.hidden = true;
tail.style.display = "none";
this.adjustLocationFloating_(message);
}
}
/**
* @return Boolean true if elt is a visible XUL element.
*/
PROT_PhishMsgDisplayerCanvas.prototype.isVisibleElement_ = function(elt) {
if (!elt)
return false;
// If it's on a collapsed/hidden toolbar, the x position is set to 0.
if (elt.boxObject.x == 0)
return false;
return true;
}
/**
* Hide the warning message from the user.
*/
PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { }
/**
* Helper class that periodically repaints the canvas. We repaint
* frequently at first, and then back off to a less frequent schedule
* at "steady state," and finally just stop altogether. We have to do
* this because we're not sure if the page has finished loading when
* we first paint the canvas, and because we want to reflect any
* dynamically written content into the canvas as it appears in the
* page after load.
*
* @param repaintFunc Function to call to repaint browser.
*
* @constructor
*/
function PROT_PhishMsgCanvasRepainter(repaintFunc) {
this.count_ = 0;
this.repaintFunc_ = repaintFunc;
this.initPeriodMS_ = 500; // Initially repaint every 500ms
this.steadyStateAtMS_ = 10 * 1000; // Go slowly after 10 seconds,
this.steadyStatePeriodMS_ = 3 * 1000; // repainting every 3 seconds, and
this.quitAtMS_ = 20 * 1000; // stop after 20 seconds
this.startMS_ = (new Date).getTime();
this.alarm_ = new G_Alarm(BindToObject(this.repaint, this),
this.initPeriodMS_);
}
/**
* Called periodically to repaint the canvas
*/
PROT_PhishMsgCanvasRepainter.prototype.repaint = function() {
this.repaintFunc_();
var nextRepaint;
// If we're in "steady state", use the slow repaint rate, else fast
if ((new Date).getTime() - this.startMS_ > this.steadyStateAtMS_)
nextRepaint = this.steadyStatePeriodMS_;
else
nextRepaint = this.initPeriodMS_;
if (!((new Date).getTime() - this.startMS_ > this.quitAtMS_))
this.alarm_ = new G_Alarm(BindToObject(this.repaint, this), nextRepaint);
}
/**
* Called to stop repainting the canvas
*/
PROT_PhishMsgCanvasRepainter.prototype.cancel = function() {
if (this.alarm_) {
this.alarm_.cancel();
this.alarm_ = null;
}
this.repaintFunc_ = null;
}

View File

@ -64,14 +64,6 @@
const kPhishWardenEnabledPref = "browser.safebrowsing.enabled";
// We have hardcoded URLs that we let people navigate to in order to
// check out the warning.
const kTestUrls = {
"http://www.google.com/tools/firefox/safebrowsing/phish-o-rama.html": true,
"http://www.mozilla.org/projects/bonecho/anti-phishing/its-a-trap.html": true,
"http://www.mozilla.com/firefox/its-a-trap.html": true,
}
/**
* Abtracts the checking of user/browser actions for signs of
* phishing.
@ -84,8 +76,6 @@ function PROT_PhishingWarden() {
PROT_ListWarden.call(this);
this.debugZone = "phishwarden";
this.testing_ = false;
this.browserViews_ = [];
// Use this to query preferences
this.prefs_ = new G_Preferences();
@ -106,9 +96,6 @@ function PROT_PhishingWarden() {
PROT_PhishingWarden.inherits(PROT_ListWarden);
/**
* We implement nsIWebProgressListener
*/
PROT_PhishingWarden.prototype.QueryInterface = function(iid) {
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsISupportsWeakReference))
@ -136,9 +123,6 @@ PROT_PhishingWarden.prototype.shutdown = function() {
* both, so eventually we will start correctly.
*/
PROT_PhishingWarden.prototype.maybeToggleUpdateChecking = function() {
if (this.testing_)
return;
var phishWardenEnabled = this.prefs_.getPref(kPhishWardenEnabledPref, null);
G_Debug(this, "Maybe toggling update checking. " +

View File

@ -1,55 +1,50 @@
<?xml version="1.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 Mozilla Reporter (r.m.o).
-
- The Initial Developer of the Original Code is
- Robert Accettura <robert@accettura.com>.
-
- Portions created by the Initial Developer are Copyright (C) 2004
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Jay Patel <jay@mozilla.org>
- Gavin Sharp <gavin@gavinsharp.com>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. 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 ***** -->
# ***** 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 Mozilla Reporter (r.m.o).
#
# The Initial Developer of the Original Code is Robert Accettura <robert@accettura.com>.
# Portions created by the Initial Developer are Copyright (C) 2004
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Jay Patel <jay@mozilla.org>
# Gavin Sharp <gavin@gavinsharp.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
<!DOCTYPE overlay [
<!ENTITY % reportphishDTD SYSTEM "chrome://browser/locale/safebrowsing/report-phishing.dtd">
%reportphishDTD;
<!ENTITY % safebrowsingDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
%safebrowsingDTD;
]>
<overlay id="reportPhishingMenuOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<broadcasterset id="mainBroadcasterSet">
<broadcaster id="reportPhishingBroadcaster" disabled="true"/>
<broadcaster id="reportPhishingErrorBroadcaster" disabled="true"/>
<!--<broadcaster id="reportPhishingErrorBroadcaster" disabled="true"/>-->
</broadcasterset>
<menupopup id="menu_HelpPopup">
<menuitem id="menu_HelpPopup_reportPhishingtoolmenu"
@ -59,12 +54,13 @@
observes="reportPhishingBroadcaster"
oncommand="openUILink(safebrowsing.getReportURL('Phish'), event);"
onclick="checkForMiddleClick(this, event);"/>
<!-- XXX Bug 415846
<menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu"
label="&safeb.palm.notforgery.label;..."
accesskey="&reportPhishSiteMenu.accesskey;"
insertbefore="updateSeparator"
observes="reportPhishingErrorBroadcaster"
oncommand="openUILinkIn(safebrowsing.getReportURL('Error'), 'tab');"
onclick="checkForMiddleClick(this, event);"/>
onclick="checkForMiddleClick(this, event);"/>-->
</menupopup>
</overlay>

View File

@ -1,77 +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 Google Safe Browsing.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Fritz Schneider <fritz@google.com> (original author)
#
# 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 ****
// A tiny class to do reporting for us. We report interesting user actions
// such as the user hitting a blacklisted page, and the user accepting
// or declining the warning.
//
// Each report has a subject and data. Current reports are:
//
// subject data meaning
// --------------------------------
// phishnavaway url the user navigated away from a phishy page
// phishdecline url the user declined our warning
// phishaccept url the user accepted our warning
// phishblhit url the user loaded a phishing page
//
// We only send reports in advanced protection mode, and even then we
// strip cookies from the request before sending it.
/**
* A very complicated class to send pings to the provider. The class does
* nothing if we're not in advanced protection mode.
*
* @constructor
*/
function PROT_Reporter() {
this.debugZone = "reporter";
this.prefs_ = new G_Preferences();
}
/**
* Send a report!
*
* @param subject String indicating what this report is about (will be
* urlencoded)
* @param data String giving extra information about this report (will be
* urlencoded)
*/
PROT_Reporter.prototype.report = function(subject, data) {
// XXX: this is disabled for now, since we don't have advanced mode
// anymore.
return;
}

View File

@ -34,108 +34,36 @@
#
# ***** END LICENSE BLOCK *****
/**
* This file is included into the main browser chrome from
* browser/base/content/global-scripts.inc
*/
var safebrowsing = {
controller: null,
phishWarden: null,
appContext: null,
startup: function() {
setTimeout(safebrowsing.deferredStartup, 2000);
// clean up
window.removeEventListener("load", safebrowsing.startup, false);
},
deferredStartup: function() {
var appContext = Cc["@mozilla.org/safebrowsing/application;1"]
.getService().wrappedJSObject;
var malwareWarden = new appContext.PROT_MalwareWarden();
safebrowsing.malwareWarden = malwareWarden;
// Register tables
malwareWarden.registerBlackTable("goog-malware-shavar");
malwareWarden.maybeToggleUpdateChecking();
var phishWarden = new appContext.PROT_PhishingWarden();
safebrowsing.phishWarden = phishWarden;
// Register tables
// XXX: move table names to a pref that we originally will download
// from the provider (need to workout protocol details)
phishWarden.registerBlackTable("goog-phish-shavar");
// Download/update lists if we're in non-enhanced mode
phishWarden.maybeToggleUpdateChecking();
safebrowsing.controller = new appContext.PROT_Controller(
window, getBrowser(), phishWarden);
},
/**
* Clean up.
*/
shutdown: function() {
if (safebrowsing.controller) {
// If the user shuts down before deferredStartup, there is no controller.
safebrowsing.controller.shutdown();
}
if (safebrowsing.phishWarden) {
safebrowsing.phishWarden.shutdown();
}
if (safebrowsing.malwareWarden) {
safebrowsing.malwareWarden.shutdown();
}
window.removeEventListener("unload", safebrowsing.shutdown, false);
this.appContext = Cc["@mozilla.org/safebrowsing/application;1"].
getService().wrappedJSObject;
this.appContext.initialize();
},
setReportPhishingMenu: function() {
var uri = getBrowser().currentURI;
if (!uri)
return;
var sbIconElt = document.getElementById("safebrowsing-urlbar-icon");
var helpMenuElt = document.getElementById("helpMenu");
var phishLevel = sbIconElt.getAttribute("level");
// Show/hide the appropriate menu item.
document.getElementById("menu_HelpPopup_reportPhishingtoolmenu")
.hidden = ("safe" != phishLevel);
document.getElementById("menu_HelpPopup_reportPhishingErrortoolmenu")
.hidden = ("safe" == phishLevel);
var broadcasterId;
if ("safe" == phishLevel) {
broadcasterId = "reportPhishingBroadcaster";
} else {
broadcasterId = "reportPhishingErrorBroadcaster";
}
var broadcaster = document.getElementById(broadcasterId);
if (!broadcaster)
return;
var progressListener =
Cc["@mozilla.org/browser/safebrowsing/navstartlistener;1"]
.createInstance(Ci.nsIDocNavStartProgressListener);
broadcaster.setAttribute("disabled", progressListener.isSpurious(uri));
var broadcaster = document.getElementById("reportPhishingBroadcaster");
if (uri && (uri.schemeIs("http") || uri.schemeIs("https")))
broadcaster.removeAttribute("disabled");
else
broadcaster.disabled = true;
},
/**
* Used to report a phishing page or a false positive
* @param name String either "Phish" or "Error"
* @return String the report phishing URL.
*/
getReportURL: function(name) {
var appContext = Cc["@mozilla.org/safebrowsing/application;1"]
.getService().wrappedJSObject;
var reportUrl = appContext.getReportURL(name);
var reportUrl = this.appContext.getReportURL(name);
var pageUrl = getBrowser().currentURI.asciiSpec;
reportUrl += "&url=" + encodeURIComponent(pageUrl);
@ -145,4 +73,3 @@ var safebrowsing = {
}
window.addEventListener("load", safebrowsing.startup, false);
window.addEventListener("unload", safebrowsing.shutdown, false);

View File

@ -1,116 +0,0 @@
<?xml version="1.0"?>
<!-- This css and dtd are for the phishing warning message -->
<?xml-stylesheet
href="chrome://browser/skin/safebrowsing/browser-protection.css"
type="text/css" ?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % safebrowsingDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
%safebrowsingDTD;
]>
<overlay id="safebrowsing-overlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<window id="main-window">
<!-- This is the spike aka tail on top of the warning -->
<hbox id="safebrowsing-palm-message-tail-container" hidden="true"
pack="end">
<image id="safebrowsing-palm-message-tail"
src="chrome://browser/skin/safebrowsing/tail.png"/>
</hbox>
<!-- This is the phishing afterload warning message -->
<vbox id="safebrowsing-palm-message" hidden="true" pack="center"
class="safebrowsing-palm-fixed-width">
<!-- This is the main warning area -->
<vbox id="safebrowsing-palm-message-content"
class="safebrowsing-palm-fixed-width"
style="-moz-user-focus: normal"
role="alert">
<hbox id="safebrowsing-palm-close-container" align="center"
class="safebrowsing-palm-fixed-width">
<spacer flex="1"/>
<image id="safebrowsing-palm-close"
onclick="goDoCommand('safebrowsing-decline-warning')"/>
</hbox>
<!-- Top line -->
<description id="safebrowsing-palm-message-titlebox"
class="safebrowsing-palm-fixed-width">
&safeb.palm.warning.title;
</description>
<!-- Content area: short warning -->
<description id="safebrowsing-palm-content"
class="safebrowsing-paragraph">
&safeb.palm.message.p1;
<label class="text-link plain"
statustext="&safeb.palm.p1.linkStatusText;"
id="safebrowsing-palm-showmore-link"
onclick="goDoCommand('safebrowsing-palm-showmore'); document.getElementById('safebrowsing-palm-faq-link').focus()"
value="&safeb.palm.message.p1.linkText;"/>
</description>
<!-- Content area: rest of the warning, revealed if the user
hits the more link -->
<vbox id="safebrowsing-palm-extended-message" hidden="true"
class="safebrowsing-palm-fixed-width">
<description class="safebrowsing-palm-paragraph">
&safeb.palm.message.p2.start;
<label class="text-link plain" id="safebrowsing-palm-faq-link"
value="&safeb.palm.message.p2.linkText;"/>
&safeb.palm.message.p2.end;
</description>
</vbox>
<!-- Main action links -->
<description id="safebrowsing-palm-message-actionbox"
class="safebrowsing-palm-fixed-width"
align="center" crop="none">
<label class="safebrowsing-palm-bigtext text-link plain"
statustext="&safeb.palm.accept.statustext;"
id="safebrowsing-palm-accept-link"
onclick="goDoCommand('safebrowsing-accept-warning')"
value="&safeb.palm.accept.label;"/>
<spacer flex="1"/>
<label class="safebrowsing-palm-bigtext text-link plain"
statustext="&safeb.palm.decline.statustext;"
id="safebrowsing-palm-decline-link"
onclick="goDoCommand('safebrowsing-decline-warning')"
value="&safeb.palm.decline.label;"/>
</description>
<!-- Footer -->
<hbox align="center" class="safebrowsing-palm-fixed-width">
<spacer flex="1"/>
<description>
[
<label id="safebrowsing-palm-falsepositive-link"
class="safebrowsing-palm-smalltext text-link plain"
value="&safeb.palm.notforgery.label;"/>
]
</description>
</hbox>
</vbox>
</vbox>
<!-- The canvas goes here, but since it takes up so much memory and is
rarely used, we add and remove it dynamically -->
<!-- This dims out the browser content -->
<vbox id="safebrowsing-dim-area-canvas" hidden="true">
</vbox>
</window>
</overlay>

View File

@ -1,7 +1,5 @@
browser.jar:
# script file included into main browser.js
* content/browser/safebrowsing/sb-loader.js (content/sb-loader.js)
+ content/browser/safebrowsing/warning-overlay.xul (content/warning-overlay.xul)
+ content/browser/safebrowsing/report-phishing-overlay.xul (content/report-phishing-overlay.xul)
+ content/browser/safebrowsing/blockedSite.xhtml (content/blockedSite.xhtml)
* content/browser/safebrowsing/report-phishing-overlay.xul (content/report-phishing-overlay.xul)
content/browser/safebrowsing/blockedSite.xhtml (content/blockedSite.xhtml)
% overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul

View File

@ -1,50 +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 mozilla.org code.
#
# The Initial Developer of the Original Code is Google Inc.
# Portions created by the Initial Developer are Copyright (C) 2006
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Brett Wilson <brettw@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = safebrowsing
XPIDL_MODULE = safebrowsing
XPIDLSRCS = nsIDocNavStartProgressListener.idl
include $(topsrcdir)/config/rules.mk

View File

@ -41,18 +41,4 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = safebrowsing
LIBRARY_NAME = safebrowsing_s
FORCE_STATIC_LIB = 1
FORCE_USE_PIC = 1
USE_STATIC_LIBS = 1
REQUIRES = \
necko \
string \
uriloader \
xpcom
CPPSRCS = nsDocNavStartProgressListener.cpp
include $(topsrcdir)/config/rules.mk

View File

@ -1,379 +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 Google Safe Browsing.
*
* The Initial Developer of the Original Code is Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brett Wilson <brettw@gmail.com>
* based on JavaScript code by Fritz Schneider <fritz@google.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsCURILoader.h"
#include "nsDocNavStartProgressListener.h"
#include "nsIChannel.h"
#include "nsINestedURI.h"
#include "nsIRequest.h"
#include "nsITimer.h"
#include "nsIURI.h"
#include "nsIWebProgress.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsStringAPI.h"
#include "prlog.h"
NS_IMPL_ISUPPORTS4(nsDocNavStartProgressListener,
nsIDocNavStartProgressListener,
nsIWebProgressListener,
nsIObserver,
nsISupportsWeakReference)
// NSPR_LOG_MODULES=DocNavStart:5
#if defined(PR_LOGGING)
static const PRLogModuleInfo *gDocNavStartProgressListenerLog = nsnull;
#define LOG(args) PR_LOG(gDocNavStartProgressListenerLog, PR_LOG_DEBUG, args)
#else
#define LOG(args)
#endif
nsDocNavStartProgressListener::nsDocNavStartProgressListener() :
mEnabled(PR_FALSE), mDelay(0), mRequests(nsnull), mTimers(nsnull)
{
#if defined(PR_LOGGING)
if (!gDocNavStartProgressListenerLog)
gDocNavStartProgressListenerLog = PR_NewLogModule("DocNavStart");
#endif
}
nsDocNavStartProgressListener::~nsDocNavStartProgressListener()
{
ClearPendingEvents();
}
void
nsDocNavStartProgressListener::ClearPendingEvents()
{
mRequests.Clear();
PRUint32 length = mTimers.Count();
for (PRUint32 i = 0; i < length; ++i) {
mTimers[i]->Cancel();
}
mTimers.Clear();
}
// nsDocNavStartProgressListener::AttachListeners
nsresult
nsDocNavStartProgressListener::AttachListeners()
{
nsresult rv;
nsCOMPtr<nsIWebProgress> webProgressService = do_GetService(
NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return webProgressService->AddProgressListener(this,
nsIWebProgress::NOTIFY_LOCATION);
}
// nsDocNavStartProgressListener::DetachListeners
nsresult
nsDocNavStartProgressListener::DetachListeners()
{
nsresult rv;
nsCOMPtr<nsIWebProgress> webProgressService = do_GetService(
NS_DOCUMENTLOADER_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return webProgressService->RemoveProgressListener(this);
}
// Helper method for checking a request URI.
nsresult
nsDocNavStartProgressListener::GetRequestUri(nsIRequest* aReq, nsIURI** uri)
{
nsCOMPtr<nsIChannel> channel;
nsresult rv;
channel = do_QueryInterface(aReq, &rv);
if (NS_FAILED(rv))
return rv;
rv = channel->GetURI(uri);
if (NS_FAILED(rv))
return rv;
return NS_OK;
}
// nsIDocNavStartProgressCallback ***********************************************
// nsDocNavStartProgressListener::GetGlobalProgressListenerEnabled
NS_IMETHODIMP
nsDocNavStartProgressListener::GetGlobalProgressListenerEnabled(PRBool* aEnabled)
{
*aEnabled = mEnabled;
return NS_OK;
}
// nsDocNavStartProgressListener::SetGlobalProgressListenerEnabled
NS_IMETHODIMP
nsDocNavStartProgressListener::SetGlobalProgressListenerEnabled(PRBool aEnabled)
{
if (aEnabled && ! mEnabled) {
// enable component
mEnabled = PR_TRUE;
return AttachListeners();
} else if (! aEnabled && mEnabled) {
// disable component
mEnabled = PR_FALSE;
return DetachListeners();
}
return NS_OK; // nothing to do
}
NS_IMETHODIMP
nsDocNavStartProgressListener::GetDelay(PRUint32* aDelay)
{
*aDelay = mDelay;
return NS_OK;
}
NS_IMETHODIMP
nsDocNavStartProgressListener::SetDelay(PRUint32 aDelay)
{
mDelay = aDelay;
return NS_OK;
}
// nsDocNavStartProgressListener::GetCallback
NS_IMETHODIMP
nsDocNavStartProgressListener::GetCallback(
nsIDocNavStartProgressCallback** aCallback)
{
NS_ENSURE_ARG_POINTER(aCallback);
*aCallback = mCallback;
NS_IF_ADDREF(*aCallback);
return NS_OK;
}
// nsDocNavStartProgressListener::SetCallback
NS_IMETHODIMP
nsDocNavStartProgressListener::SetCallback(
nsIDocNavStartProgressCallback* aCallback)
{
mCallback = aCallback;
// Break any cycles we have from mTimers to us by clearing all pending
// requests and timers; the timers we use are not exposed externally, but
// since we use ourself as an observer with each timer, we have to
// manually break this cycle to ensure prompt destruction of this and
// the release of everything this entrains, in the case that we can't wait
// for all the timers to expire normally for some reason (e.g. application
// shutdown).
if (!aCallback)
ClearPendingEvents();
return NS_OK;
}
NS_IMETHODIMP
nsDocNavStartProgressListener::IsSpurious(nsIURI* aURI, PRBool* isSpurious)
{
NS_PRECONDITION(aURI, "Must have a URI!");
nsCAutoString scheme;
nsresult rv;
// If there's a nested URI, we want to check the inner URI's scheme.
// If we find a spurious scheme then we can break the checking loop at that point.
nsCOMPtr<nsIURI> inner = aURI;
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(inner);
while (true) {
rv = inner->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
*isSpurious = scheme.Equals("about") ||
scheme.Equals("chrome") ||
scheme.Equals("file") ||
scheme.Equals("javascript");
if (*isSpurious || !nestedURI)
break;
rv = nestedURI->GetInnerURI(getter_AddRefs(inner));
NS_ENSURE_SUCCESS(rv, rv);
nestedURI = do_QueryInterface(inner);
}
return NS_OK;
}
// nsIWebProgressListener ******************************************************
// nsDocNavStartProgressListener::OnStateChange
NS_IMETHODIMP
nsDocNavStartProgressListener::OnStateChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 aStateFlags,
nsresult aStatus)
{
return NS_OK;
}
// nsDocNavStartProgressListener::OnProgressChange
NS_IMETHODIMP
nsDocNavStartProgressListener::OnProgressChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRInt32 aCurSelfProgress, PRInt32 aMaxSelfProgress,
PRInt32 aCurTotalProgress,
PRInt32 aMaxTotalProgress)
{
return NS_OK;
}
// nsDocNavStartProgressListener::OnLocationChange
NS_IMETHODIMP
nsDocNavStartProgressListener::OnLocationChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsIURI *aLocation)
{
nsresult rv;
nsCAutoString uriString;
nsCOMPtr<nsIURI> uri;
// ignore requests with no URI
rv = GetRequestUri(aRequest, getter_AddRefs(uri));
if (NS_FAILED(rv))
return NS_OK;
rv = uri->GetAsciiSpec(uriString);
if (NS_FAILED(rv))
return NS_OK;
LOG(("Firing OnLocationChange for %s", uriString.get()));
// We store the request and a timer in queue. When the timer fires,
// we use the request in the front of the queue.
nsCOMPtr<nsITimer> timer = do_CreateInstance("@mozilla.org/timer;1", &rv);
NS_ENSURE_TRUE(timer, rv);
rv = timer->Init(this, mDelay, nsITimer::TYPE_ONE_SHOT);
NS_ENSURE_SUCCESS(rv, rv);
mRequests.AppendObject(aRequest);
mTimers.AppendObject(timer);
return NS_OK;
}
// nsDocNavStartProgressListener::OnStatusChange
NS_IMETHODIMP
nsDocNavStartProgressListener::OnStatusChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsresult aStatus,
const PRUnichar *aMessage)
{
return NS_OK;
}
// nsDocNavStartProgressListener::OnSecurityChange
NS_IMETHODIMP
nsDocNavStartProgressListener::OnSecurityChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
PRUint32 aState)
{
return NS_OK;
}
// nsIObserver ****************************************************************
NS_IMETHODIMP
nsDocNavStartProgressListener::Observe(nsISupports *subject, const char *topic,
const PRUnichar *data)
{
if (strcmp(topic, NS_TIMER_CALLBACK_TOPIC) == 0) {
// Timer callback, pop the front of the request queue and call the callback.
#ifdef DEBUG
PRUint32 length = mRequests.Count();
NS_ASSERTION(length > 0, "timer callback with empty request queue?");
length = mTimers.Count();
NS_ASSERTION(length > 0, "timer callback with empty timer queue?");
#endif
nsIRequest* request = mRequests[0];
if (mCallback) {
PRBool isSpurious;
nsCOMPtr<nsIURI> uri;
nsresult rv = GetRequestUri(request, getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
rv = IsSpurious(uri, &isSpurious);
NS_ENSURE_SUCCESS(rv, rv);
if (!isSpurious) {
nsCString uriString;
rv = uri->GetAsciiSpec(uriString);
NS_ENSURE_SUCCESS(rv, rv);
// We don't care about URL fragments so we take that off.
PRInt32 pos = uriString.FindChar('#');
if (pos > -1) {
uriString.SetLength(pos);
}
LOG(("Firing DocNavStart for %s", uriString.get()));
mCallback->OnDocNavStart(request, uriString);
}
}
mRequests.RemoveObjectAt(0);
mTimers.RemoveObjectAt(0);
}
return NS_OK;
}

View File

@ -11,15 +11,10 @@ Function.prototype.inherits = function(parentCtor) {
}
#include ../content/application.js
#include ../content/browser-view.js
#include ../content/controller.js
#include ../content/firefox-commands.js
#include ../content/globalstore.js
#include ../content/list-warden.js
#include ../content/phishing-afterload-displayer.js
#include ../content/phishing-warden.js
#include ../content/malware-warden.js
#include ../content/reporter.js
var modScope = this;
function Init() {

View File

@ -1,2 +0,0 @@
browser.jar:
+ content/browser/protection/unittests.xul (unittests.xul)

View File

@ -1,70 +0,0 @@
<?xml version="1.0"?>
<window id="PROT_unittest"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="onProtUnittestLoad();"
title="prot unittests">
<script><![CDATA[
const Cc = Components.classes;
const Ci = Components.interfaces;
function G_Debug(zone, s) {
var label = document.createElement('label');
var txt = "[" + zone + "] " + s;
label.appendChild(document.createTextNode(txt));
document.documentElement.appendChild(label);
}
function G_Assert(zone, cond, msg) {
if (!cond) {
G_Debug(zone, msg);
throw msg;
}
}
function ProtectionPhishWardenTests() {
var z = "phishwarden UNITTEST";
G_Debug(z, "Starting");
var listManager = Cc["@mozilla.org/protection/protectionlistmanager;1"]
.getService(Ci.nsIProtectionListManager);
var warden = Cc['@mozilla.org/protection/phishwarden;1']
.createInstance(Ci.nsIProtectionListWarden);
// Register tables that we are interested in.
warden.registerBlackTable("test-black-url");
var blacklistedCount = 0;
var blackURLs = [
"http://foo.com/1",
"http://foo.com/2",
"http://foo.com/3",
"http://foo.com/4",
"http://www.goodsite.com/test",
];
for (var i = 0; i < blackURLs.length; i++)
listManager.safeInsert("test-black-url", blackURLs[i], "1");
G_Assert(z, !warden.checkUrl("http://bar.com/"), 'should not have found');
G_Assert(z, warden.checkUrl("http://foo.com/1"), 'should have found (1)');
G_Assert(z, warden.checkUrl("http://foo.com/2"), 'should have found (2)');
G_Assert(z, warden.checkUrl("http://foo.com/3"), 'should have found (3)');
G_Assert(z, warden.checkUrl("http://foo.com/4"), 'should have found (4)');
warden.registerWhiteTable('test-white-domain');
listManager.safeInsert("test-white-domain", "http://www.goodsite.com/", "1");
G_Assert(z, !warden.checkUrl("http://www.goodsite.com/"),
'whitelist failed?')
G_Debug(z, "PASSED");
}
function onProtUnittestLoad() {
ProtectionPhishWardenTests();
}
]]></script>
</window>

View File

@ -1396,7 +1396,7 @@ Engine.prototype = {
this._urls.push(new EngineURL("text/html", aMethod, aTemplate));
this._name = aName;
this._alias = aAlias;
this.alias = aAlias;
this._description = aDescription;
this._setIcon(aIconURL, true);
@ -1526,9 +1526,6 @@ Engine.prototype = {
break;
// Non-OpenSearch elements
case "Alias":
this._alias = child.textContent;
break;
case "SearchForm":
this._searchForm = child.textContent;
break;
@ -1905,7 +1902,6 @@ Engine.prototype = {
}
}
appendTextNode(MOZSEARCH_NS_10, "Alias", this.alias);
appendTextNode(MOZSEARCH_NS_10, "UpdateInterval", this._updateInterval);
appendTextNode(MOZSEARCH_NS_10, "UpdateUrl", this._updateURL);
appendTextNode(MOZSEARCH_NS_10, "IconUpdateUrl", this._iconUpdateURL);

View File

@ -45,6 +45,8 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_TEST_FILES = browser_405664.js \
browser_415700.js \
testEngine.xml \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

View File

@ -0,0 +1,90 @@
/* ***** 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 mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Ryan Flint <rflint@dslr.net> (Original Author)
*
* 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 ***** */
var gSS = Cc["@mozilla.org/browser/search-service;1"].
getService(Ci.nsIBrowserSearchService);
var gObs = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
var observers = {
observe: function(aSubject, aTopic, aData) {
switch (aData) {
case "engine-added":
test2();
break;
case "engine-current":
test3();
break;
case "engine-removed":
test4();
break;
}
}
};
function test() {
waitForExplicitFinish();
gObs.addObserver(observers, "browser-search-engine-modified", false);
gSS.addEngine("http://localhost:8888/browser/browser/components/search/test/testEngine.xml",
Ci.nsISearchEngine.DATA_XML, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
false);
}
function test2() {
var engine = gSS.getEngineByName("Foo");
ok(engine, "Engine was added.");
var aEngine = gSS.getEngineByAlias("fooalias");
ok(!aEngine, "Alias was not parsed from engine description");
gSS.currentEngine = engine;
}
function test3() {
var engine = gSS.currentEngine;
is(engine.name, "Foo", "Current engine was changed successfully");
gSS.removeEngine(engine);
}
function test4() {
var engine = gSS.currentEngine;
ok(engine, "An engine is present.");
isnot(engine.name, "Foo", "Current engine reset after removal");
gObs.removeObserver(observers, "browser-search-engine-modified");
finish();
}

View File

@ -0,0 +1,12 @@
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/"
xmlns:moz="http://www.mozilla.org/2006/browser/search/">
<ShortName>Foo</ShortName>
<Description>Foo Search</Description>
<InputEncoding>utf-8</InputEncoding>
<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC</Image>
<Url type="text/html" method="GET" template="http://localhost:8888/browser/browser/components/search/test/?search">
<Param name="test" value="{searchTerms}"/>
</Url>
<moz:SearchForm>http://localhost:8888/browser/browser/components/search/test/</moz:SearchForm>
<moz:Alias>fooalias</moz:Alias>
</OpenSearchDescription>

View File

@ -506,6 +506,13 @@ SessionStoreService.prototype = {
// cache the window state until the window is completely gone
aWindow.__SS_dyingCache = this._windows[aWindow.__SSi] || this._lastWindowClosed;
// reset the _tab property to avoid keeping the tab's XUL element alive
// longer than we need it
var tabCount = aWindow.__SS_dyingCache.tabs.length;
for (var t = 0; t < tabCount; t++) {
delete aWindow.__SS_dyingCache.tabs[t]._tab;
}
delete aWindow.__SSi;
},
@ -575,6 +582,10 @@ SessionStoreService.prototype = {
// make sure that the tab related data is up-to-date
var tabState = this._collectTabData(aTab);
this._updateTextAndScrollDataForTab(aWindow, aTab.linkedBrowser, tabState);
// reset the _tab property to avoid keeping the tab's XUL element alive
// longer than we need it
delete tabState._tab;
// store closed-tab data for undo
if (tabState.entries.length > 1 || tabState.entries[0].url != "about:blank") {

View File

@ -47,5 +47,5 @@ MOZ_MORKREADER=1
MOZ_SAFE_BROWSING=1
MOZ_APP_VERSION=$FIREFOX_VERSION
MOZ_NO_XPCOM_OBSOLETE=1
MOZ_EXTENSIONS_DEFAULT=" inspector gnomevfs reporter"
MOZ_EXTENSIONS_DEFAULT=" gnomevfs reporter"
# MOZ_APP_DISPLAYNAME will be set by branding/configure.sh

View File

@ -87,6 +87,14 @@ extensions/reporter@mozilla.org/install.rdf
extensions/reporter@mozilla.org/chrome.manifest
extensions/reporter@mozilla.org/chrome/reporter.jar
extensions/reporter@mozilla.org/defaults/preferences/reporter.js
#Remove Inspector (present from upgrades from Fx2/Fx3b1)
components/inspector.xpt
extensions/inspector@mozilla.org/install.rdf
extensions/inspector@mozilla.org/components/inspector-cmdline.js
extensions/inspector@mozilla.org/chrome.manifest
extensions/inspector@mozilla.org/chrome/inspector.jar
extensions/inspector@mozilla.org/defaults/preferences/inspector.js
extensions/inspector@mozilla.org/platform/WINNT/chrome/icons/default/winInspectorMain.ico
extensions/inspector@mozilla.org/components/inspector.xpt
extensions/inspector@mozilla.org/components/@DLL_PREFIX@inspector@DLL_SUFFIX@
extensions/inspector@mozilla.org/chrome/icons/default/winInspectorMain.ico
@ -575,12 +583,24 @@ components/xpcom_obsolete.xpt
init.d/README
redo-prebinding.sh
res/viewer.properties
res/bloatcycle.html
#endif
#ifdef XP_UNIX
#ifndef XP_MACOSX
readme.txt
chrome/icons/default/default.xpm
#endif
#endif
dictionaries/PL.dic
dictionaries/PL.aff
#ifdef MOZ_MEMORY
#ifdef XP_WIN
Microsoft.VC80.CRT.manifest
msvcm80.dll
msvcp80.dll
msvcr80.dll
#endif
#endif
#ifdef XP_WIN
xpicleanup.exe
#else

View File

@ -349,11 +349,3 @@ bin\crashreporter.exe
bin\crashreporter.ini
bin\crashreporter-override.ini
; [Additional Developer Tools]
[adt]
bin\extensions\inspector@mozilla.org\install.rdf
bin\extensions\inspector@mozilla.org\components\inspector-cmdline.js
bin\extensions\inspector@mozilla.org\chrome.manifest
bin\extensions\inspector@mozilla.org\chrome\inspector.jar
bin\extensions\inspector@mozilla.org\defaults\preferences\inspector.js
bin\extensions\inspector@mozilla.org\platform\WINNT\chrome\icons\default\winInspectorMain.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 856 B

After

Width:  |  Height:  |  Size: 865 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 924 B

After

Width:  |  Height:  |  Size: 928 B

View File

@ -187,10 +187,12 @@ menuitem.bookmark-item {
list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
}
/* livemarks have the same layout as folder-item, but in the browser-only livemark-item.png */
/* only the folder icon has any effect for now, item icon is unused */
.bookmark-item[container][livemark] {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
}
.bookmark-item[container][livemark] .bookmark-item {
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
}
.bookmark-item[container][tagContainer] {
@ -209,13 +211,15 @@ menuitem:not([type]) {
}
menuitem[command="cmd_newNavigator"],
#context-openlink {
#context-openlink,
#context-openframe {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 80px 16px 64px);
}
menuitem[command="cmd_newNavigatorTab"],
#context-openlinkintab {
#context-openlinkintab,
#context-openframeintab {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 64px 16px 48px);
}
@ -231,7 +235,8 @@ menuitem[command="Browser:OpenFile"] {
menuitem[command="Browser:SavePage"],
#context-savelink,
#context-saveimage,
#context-savepage {
#context-savepage,
#context-saveframe {
list-style-image: url("moz-icon://stock/gtk-save-as?size=menu");
}
@ -239,7 +244,8 @@ menuitem[command="cmd_printPreview"] {
list-style-image: url("moz-icon://stock/gtk-print-preview?size=menu");
}
menuitem[command="cmd_print"] {
menuitem[command="cmd_print"],
#context-printframe {
list-style-image: url("moz-icon://stock/gtk-print?size=menu");
}
@ -278,7 +284,8 @@ menuitem[command="cmd_cut"][disabled],
menuitem[command="cmd_copy"],
#context-copy,
#context-copyimage,
#context-copylink {
#context-copylink,
#context-copyemail {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}
@ -324,8 +331,7 @@ menuitem[command="cmd_selectAll"] {
}
menuitem[command="Browser:Stop"],
#context-stop,
#javascriptConsole {
#context-stop {
list-style-image: url("moz-icon://stock/gtk-stop?size=menu");
}
@ -335,7 +341,8 @@ menuitem[command="Browser:Stop"][disabled],
}
menuitem[command="Browser:Reload"],
#context-reload {
#context-reload,
#context-reloadframe {
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
}
@ -416,7 +423,8 @@ menuitem[command="Browser:ShowAllBookmarks"] {
}
menuitem[command="View:PageInfo"],
#context-viewinfo {
#context-viewinfo,
#context-viewframeinfo {
list-style-image: url("moz-icon://stock/gtk-info?size=menu");
}
@ -436,6 +444,10 @@ menuitem[key="key_openHelp"] {
list-style-image: url("moz-icon://stock/gtk-about?size=menu");
}
#javascriptConsole {
list-style-image: url("chrome://global/skin/console/console.png");
}
/* Primary toolbar buttons */
.toolbarbutton-1 {
-moz-box-orient: vertical;
@ -600,6 +612,9 @@ toolbar[iconsize="small"] .toolbarbutton-1[type="menu-button"] {
toolbar[iconsize="small"] #back-button {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu");
}
.unified-nav-back[_moz-menuactive] {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu") !important;
}
toolbar[iconsize="small"] #back-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-go-back-ltr?size=menu&state=disabled");
}
@ -607,6 +622,9 @@ toolbar[iconsize="small"] #back-button[disabled="true"] {
toolbar[iconsize="small"] #back-button[chromedir="rtl"] {
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu");
}
menupopup[chromedir="rtl"] > .unified-nav-back[_moz-menuactive] {
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu") !important;
}
toolbar[iconsize="small"] #back-button[disabled="true"][chromedir="rtl"] {
list-style-image: url("moz-icon://stock/gtk-go-back-rtl?size=menu&state=disabled");
}
@ -614,6 +632,9 @@ toolbar[iconsize="small"] #back-button[disabled="true"][chromedir="rtl"] {
toolbar[iconsize="small"] #forward-button {
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu");
}
.unified-nav-forward[_moz-menuactive] {
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu") !important;
}
toolbar[iconsize="small"] #forward-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-go-forward-ltr?size=menu&state=disabled");
}
@ -621,6 +642,9 @@ toolbar[iconsize="small"] #forward-button[disabled="true"] {
toolbar[iconsize="small"] #forward-button[chromedir="rtl"] {
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu");
}
menupopup[chromedir="rtl"] > .unified-nav-forward[_moz-menuactive] {
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu") !important;
}
toolbar[iconsize="small"] #forward-button[disabled="true"][chromedir="rtl"] {
list-style-image: url("moz-icon://stock/gtk-go-forward-rtl?size=menu&state=disabled");
}
@ -796,33 +820,34 @@ toolbar[iconsize="small"] #paste-button[disabled="true"] {
}
/* Favicon */
#page-proxy-deck,
#page-proxy-stack,
#page-proxy-favicon,
#page-proxy-button {
#urlbar-throbber {
width: 16px;
height: 16px;
}
#page-proxy-deck {
#page-proxy-stack {
margin: 2px 3px;
}
#page-proxy-favicon {
list-style-image: none;
#page-proxy-favicon:not([src]) {
list-style-image: url("chrome://global/skin/icons/folder-item.png");
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
#page-proxy-button {
list-style-image: url("chrome://global/skin/icons/folder-item.png") !important;
-moz-image-region: rect(0px, 16px, 16px, 0px);}
#page-proxy-favicon[pageproxystate="invalid"] {
-moz-image-region: rect(16px, 16px, 32px, 0px);
}
#page-proxy-button[pageproxystate="invalid"] {
cursor: default;
-moz-image-region: rect(32px, 16px, 48px, 0px) !important;
#urlbar-throbber {
list-style-image: url("chrome://global/skin/throbber/Throbber-small.gif");
}
/* Identity indicator */
#identity-box {
background-color: -moz-dialog;
color: -moz-dialogtext;
-moz-border-end: 1px solid ThreeDShadow;
}
@ -1186,6 +1211,35 @@ tabpanels {
border-bottom: 1px solid threedshadow;
}
#context_newTab {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 64px 16px 48px);
}
#context_newTab[disabled] {
-moz-image-region: rect(16px 64px 32px 48px);
}
#context_reloadTab {
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
}
#context_closeOtherTabs {
list-style-image: url("moz-icon://stock/gtk-clear?size=menu");
}
#context_closeOtherTabs[disabled] {
list-style-image: url("moz-icon://stock/gtk-clear?size=menu&state=disabled");
}
#context_undoCloseTab {
list-style-image: url("moz-icon://stock/gtk-undelete?size=menu");
}
#context_closeTab {
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
}
/* tabbrowser-tab focus ring */
.tabbrowser-tab > .tab-text {
border: 1px dotted transparent;
@ -1272,6 +1326,10 @@ tabpanels {
opacity: 0.6;
}
.tabs-alltabs-button > .toolbarbutton-icon {
margin: 0px;
}
/* Sidebar */
#sidebar-box .tabs-closebutton {
margin-bottom: 0px !important;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -33,10 +33,7 @@ classic.jar:
* skin/classic/browser/places/bookmarkProperties.css (places/bookmarkProperties.css)
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
* skin/classic/browser/places/editBookmarkOverlay.css (places/editBookmarkOverlay.css)
skin/classic/browser/places/livemark-folder.png (places/livemark-folder.png)
skin/classic/browser/places/livemark-folder-rtl.png (places/livemark-folder-rtl.png)
skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/browser/places/livemark-item-rtl.png (places/livemark-item-rtl.png)
skin/classic/browser/places/pageStarred.png (places/pageStarred.png)
skin/classic/browser/places/starred48.png (places/starred48.png)
skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
@ -54,14 +51,6 @@ classic.jar:
skin/classic/browser/preferences/plugin.png (preferences/plugin.png)
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
#ifdef MOZ_SAFE_BROWSING
skin/classic/browser/safebrowsing/browser-protection.css (safebrowsing/browser-protection.css)
skin/classic/browser/safebrowsing/close16x16.png (safebrowsing/close16x16.png)
skin/classic/browser/safebrowsing/dim.png (safebrowsing/dim.png)
skin/classic/browser/safebrowsing/tail.png (safebrowsing/tail.png)
skin/classic/browser/safebrowsing/warning16x16.png (safebrowsing/warning16x16.png)
skin/classic/browser/safebrowsing/warning24x24.png (safebrowsing/warning24x24.png)
#endif
skin/classic/browser/tabbrowser/tab-arrow-end.png (tabbrowser/tab-arrow-end.png)
skin/classic/browser/tabbrowser/tab-arrow-start.png (tabbrowser/tab-arrow-start.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)

View File

@ -62,42 +62,22 @@
-moz-image-region: rect(0px, 32px, 32px, 0px)
}
#generalTab:hover, #generalTab[selected="true"] {
-moz-image-region: rect(32px, 32px, 64px, 0px)
}
#mediaTab {
-moz-image-region: rect(0px, 64px, 32px, 32px)
}
#mediaTab:hover, #mediaTab[selected="true"] {
-moz-image-region: rect(32px, 64px, 64px, 32px)
}
#feedTab {
-moz-image-region: rect(0px, 96px, 32px, 64px)
}
#feedTab:hover, #feedTab[selected="true"] {
-moz-image-region: rect(32px, 96px, 64px, 64px)
}
#permTab {
-moz-image-region: rect(0px, 128px, 32px, 96px)
}
#permTab:hover, #permTab[selected="true"] {
-moz-image-region: rect(32px, 128px, 64px, 96px)
}
#securityTab {
-moz-image-region: rect(0px, 160px, 32px, 128px)
}
#securityTab:hover, #securityTab[selected="true"] {
-moz-image-region: rect(32px, 160px, 64px, 128px)
}
deck {
padding: 10px 10px 10px 10px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 732 B

View File

@ -268,84 +268,10 @@
}
/**** menuitem stock icons ****/
menuitem:not([type]) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
menuitem[command="cmd_cut"] {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
}
menuitem[command="cmd_cut"][disabled] {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu&state=disabled");
}
menuitem[command="cmd_copy"] {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}
menuitem[command="cmd_copy"][disabled] {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu&state=disabled");
}
menuitem[command="cmd_paste"] {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
}
menuitem[command="cmd_paste"][disabled] {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
}
menuitem[command="cmd_delete"] {
list-style-image: url("moz-icon://stock/gtk-delete?size=menu");
}
menuitem[command="cmd_delete"][disabled] {
list-style-image: url("moz-icon://stock/gtk-delete?size=menu&state=disabled");
}
menuitem[command="cmd_undo"] {
list-style-image: url("moz-icon://stock/gtk-undo?size=menu");
}
menuitem[command="cmd_undo"][disabled] {
list-style-image: url("moz-icon://stock/gtk-undo?size=menu&state=disabled");
}
menuitem[command="cmd_redo"] {
list-style-image: url("moz-icon://stock/gtk-redo?size=menu");
}
menuitem[command="cmd_redo"][disabled] {
list-style-image: url("moz-icon://stock/gtk-redo?size=menu&state=disabled");
}
menuitem[command="cmd_selectAll"] {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
}
menuitem[command="cmd_selectAll"][disabled] {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu&state=disabled");
}
#orgClose {
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
}
menuitem[command="placesCmd_open:window"] {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 80px 16px 64px);
}
menuitem[command="placesCmd_open:tab"] {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 64px 16px 48px);
}
menuitem[command="placesCmd_show:info"] {
list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
}
menuitem[command="OrganizerCommand_import"] {
list-style-image: url("moz-icon://stock/gtk-revert-to-saved?size=menu");
}

View File

@ -35,7 +35,7 @@ treechildren::-moz-tree-image(title, container) {
}
treechildren::-moz-tree-image(title, container, livemark) {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
-moz-image-region: auto;
}
@ -50,6 +50,12 @@ treechildren::-moz-tree-image(title, query) {
-moz-image-region: auto;
}
/* We want some queries to look like ordinary folders. This must come
after the (title, query) selector, or it would get overridden. */
treechildren::-moz-tree-image(title, query, folder) {
list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
}
treechildren::-moz-tree-row(session-start) {
border-top:1px dotted ThreeDShadow;
font-weight: bold;
@ -58,3 +64,90 @@ treechildren::-moz-tree-row(session-start) {
treechildren::-moz-tree-cell-text(date, session-continue) {
color: -moz-Field;
}
/**** menuitem stock icons ****/
menuitem:not([type]) {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
menuitem[command="cmd_cut"],
menuitem[cmd="cmd_cut"] {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu");
}
menuitem[command="cmd_cut"][disabled]
menuitem[cmd="cmd_cut"][disabled] {
list-style-image: url("moz-icon://stock/gtk-cut?size=menu&state=disabled");
}
menuitem[command="cmd_copy"],
menuitem[cmd="cmd_copy"] {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu");
}
menuitem[command="cmd_copy"][disabled]
menuitem[cmd="cmd_copy"][disabled] {
list-style-image: url("moz-icon://stock/gtk-copy?size=menu&state=disabled");
}
menuitem[command="cmd_paste"],
menuitem[cmd="cmd_paste"] {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu");
}
menuitem[command="cmd_paste"][disabled],
menuitem[cmd="cmd_paste"][disabled] {
list-style-image: url("moz-icon://stock/gtk-paste?size=menu&state=disabled");
}
menuitem[command="cmd_delete"],
menuitem[cmd="cmd_delete"] {
list-style-image: url("moz-icon://stock/gtk-delete?size=menu");
}
menuitem[command="cmd_delete"][disabled],
menuitem[cmd="cmd_delete"][disabled] {
list-style-image: url("moz-icon://stock/gtk-delete?size=menu&state=disabled");
}
menuitem[command="cmd_undo"],
menuitem[cmd="cmd_undo"] {
list-style-image: url("moz-icon://stock/gtk-undo?size=menu");
}
menuitem[command="cmd_undo"][disabled],
menuitem[cmd="cmd_undo"][disabled] {
list-style-image: url("moz-icon://stock/gtk-undo?size=menu&state=disabled");
}
menuitem[command="cmd_redo"] {
list-style-image: url("moz-icon://stock/gtk-redo?size=menu");
}
menuitem[command="cmd_redo"][disabled] {
list-style-image: url("moz-icon://stock/gtk-redo?size=menu&state=disabled");
}
menuitem[command="cmd_selectAll"],
menuitem[cmd="cmd_selectAll"] {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu");
}
menuitem[command="cmd_selectAll"][disabled],
menuitem[cmd="cmd_selectAll"][disabled] {
list-style-image: url("moz-icon://stock/gtk-select-all?size=menu&state=disabled");
}
menuitem[command="placesCmd_open:window"] {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 80px 16px 64px);
}
menuitem[command="placesCmd_open:tab"] {
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
-moz-image-region: rect(0px 64px 16px 48px);
}
menuitem[command="placesCmd_show:info"] {
list-style-image: url("moz-icon://stock/gtk-properties?size=menu");
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

After

Width:  |  Height:  |  Size: 583 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 565 B

View File

@ -1,116 +0,0 @@
#safebrowsing-palm-message {
display: none;
position: fixed;
top: 0px;
left: 0px;
z-index: 2;
}
#safebrowsing-palm-message-content {
background-color: white;
color: black;
-moz-box-sizing: border-box;
-moz-border-radius: 10px;
padding: 10px;
border-top: 1px solid;
border-left: 1px solid;
border-right: 2px solid;
border-bottom: 2px solid;
z-index: 1;
margin: 0;
font-size: 120%;
}
.safebrowsing-palm-fixed-width {
width: 400px;
max-width: 400px;
}
.safebrowsing-palm-paragraph {
padding-bottom: 2em;
}
#safebrowsing-palm-close-container {
height: 16px;
margin: 0;
padding: 0;
}
#safebrowsing-palm-close {
cursor: pointer;
height: 16px;
width: 16px;
list-style-image: url("chrome://browser/skin/safebrowsing/close16x16.png");
z-index: 10;
}
#safebrowsing-palm-message-tail-container {
display: none;
position: fixed;
top: 0px;
left: 0px;
border-right: 2px solid;
z-index: 3;
height: 67px;
margin: 0;
padding: 0;
}
#safebrowsing-palm-message-tail {
height: 67px;
width: 24px;
max-width: 24px;
z-index: 3;
}
#safebrowsing-palm-message-titlebox {
background-image: url("chrome://browser/skin/safebrowsing/warning24x24.png");
background-repeat: no-repeat;
background-position: top left;
text-indent: 30px;
padding: 0 0 5px;
margin-top: -16px;
font-size: 120%;
font-weight: bold;
min-height: 26px;
}
#safebrowsing-palm-message-actionbox {
padding: 10px 10px 15px;
text-align: center;
}
.safebrowsing-palm-bigtext {
font-weight: bold;
}
.safebrowsing-palm-smalltext {
font-size: 80%;
}
#safebrowsing-palm-google-logo {
height: 32px;
max-height: 32px;
width: 78px;
}
#safebrowsing-page-canvas {
position: fixed;
}
#safebrowsing-dim-area-canvas {
background-image: url("chrome://browser/skin/safebrowsing/dim.png");
position: fixed;
}
#safebrowsing-urlbar-icon {
padding: 1px 2px 1px 0;
}
#safebrowsing-urlbar-icon[level="safe"] {
list-style-image: none;
}
#safebrowsing-urlbar-icon[level="warn"] {
list-style-image: url("chrome://browser/skin/safebrowsing/warning16x16.png");
}

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