Merge m-c to s-c.
|
@ -43,7 +43,7 @@
|
|||
|
||||
interface nsIEditor;
|
||||
|
||||
[scriptable, uuid(52837507-202d-4e72-a482-5f068a1fd720)]
|
||||
[scriptable, uuid(e242d495-5cde-4b1c-8c84-2525b14939f5)]
|
||||
interface nsIAccessibleEditableText : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -103,19 +103,4 @@ interface nsIAccessibleEditableText : nsISupports
|
|||
* clipboard into the text represented by this object.
|
||||
*/
|
||||
void pasteText (in long position);
|
||||
|
||||
/**
|
||||
* Returns an editor associated with the accessible.
|
||||
*/
|
||||
[noscript] readonly attribute nsIEditor associatedEditor;
|
||||
};
|
||||
|
||||
/*
|
||||
Assumptions:
|
||||
|
||||
selectAttributes method takes an nsISupports parameter.
|
||||
'set' methods throw exception on failure.
|
||||
'wstring' inputs are potentially multibyte (UTF-16 for
|
||||
instance); 'string' and UTF-8 may be a better choice.
|
||||
|
||||
*/
|
||||
|
|
|
@ -680,8 +680,7 @@ NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
|
|||
|
||||
// Don't fire event for the first html:br in an editor.
|
||||
if (aEvent->mAccessible->Role() == roles::WHITESPACE) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
textAccessible->GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = textAccessible->GetEditor();
|
||||
if (editor) {
|
||||
bool isEmpty = false;
|
||||
editor->GetDocumentIsEmpty(&isEmpty);
|
||||
|
|
|
@ -214,6 +214,11 @@ public:
|
|||
*/
|
||||
virtual PRUint64 NativeState();
|
||||
|
||||
/**
|
||||
* Return bit set of invisible and offscreen states.
|
||||
*/
|
||||
PRUint64 VisibilityState();
|
||||
|
||||
/**
|
||||
* Returns attributes for accessible without explicitly setted ARIA
|
||||
* attributes.
|
||||
|
@ -702,8 +707,6 @@ protected:
|
|||
virtual nsIFrame* GetBoundsFrame();
|
||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
|
||||
PRUint64 VisibilityState();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Name helpers
|
||||
|
||||
|
|
|
@ -333,8 +333,7 @@ nsDocAccessible::NativeState()
|
|||
state |= states::INVISIBLE | states::OFFSCREEN;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
state |= editor ? states::EDITABLE : states::READONLY;
|
||||
|
||||
return state;
|
||||
|
@ -553,37 +552,32 @@ nsDocAccessible::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibleHyperText method
|
||||
NS_IMETHODIMP nsDocAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
// nsHyperTextAccessible method
|
||||
already_AddRefed<nsIEditor>
|
||||
nsDocAccessible::GetEditor() const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEditor);
|
||||
*aEditor = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Check if document is editable (designMode="on" case). Otherwise check if
|
||||
// the html:body (for HTML document case) or document element is editable.
|
||||
if (!mDocument->HasFlag(NODE_IS_EDITABLE) &&
|
||||
!mContent->HasFlag(NODE_IS_EDITABLE))
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
|
||||
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(container));
|
||||
if (!editingSession)
|
||||
return NS_OK; // No editing session interface
|
||||
return nsnull; // No editing session interface
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editingSession->GetEditorForWindow(mDocument->GetWindow(), getter_AddRefs(editor));
|
||||
if (!editor) {
|
||||
return NS_OK;
|
||||
}
|
||||
bool isEditable;
|
||||
if (!editor)
|
||||
return nsnull;
|
||||
|
||||
bool isEditable = false;
|
||||
editor->GetIsDocumentEditable(&isEditable);
|
||||
if (isEditable) {
|
||||
NS_ADDREF(*aEditor = editor);
|
||||
}
|
||||
return NS_OK;
|
||||
if (isEditable)
|
||||
return editor.forget();
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// nsDocAccessible public method
|
||||
|
|
|
@ -133,8 +133,8 @@ public:
|
|||
virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
|
||||
#endif
|
||||
|
||||
// nsIAccessibleText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsDocAccessible
|
||||
|
||||
|
|
|
@ -544,11 +544,12 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::DoAction(PRUint8 index)
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsHTMLTextFieldAccessible::GetEditor() const
|
||||
{
|
||||
*aEditor = nsnull;
|
||||
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent));
|
||||
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
|
||||
if (!editableElt)
|
||||
return nsnull;
|
||||
|
||||
// nsGenericHTMLElement::GetEditor has a security check.
|
||||
// Make sure we're not restricted by the permissions of
|
||||
|
@ -558,7 +559,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor
|
|||
bool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
nsresult rv = editableElt->GetEditor(aEditor);
|
||||
editableElt->GetEditor(getter_AddRefs(editor));
|
||||
|
||||
if (pushed) {
|
||||
JSContext* cx;
|
||||
|
@ -566,7 +567,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor
|
|||
NS_ASSERTION(!cx, "context should be null");
|
||||
}
|
||||
|
||||
return rv;
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -138,8 +138,8 @@ public:
|
|||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual void ApplyARIAState(PRUint64* aState);
|
||||
|
|
|
@ -166,8 +166,7 @@ nsHyperTextAccessible::NativeState()
|
|||
{
|
||||
PRUint64 states = nsAccessibleWrap::NativeState();
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
PRUint32 flags;
|
||||
editor->GetFlags(&flags);
|
||||
|
@ -711,8 +710,7 @@ nsHyperTextAccessible::HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
|||
// If the given offsets are 0 and associated editor is empty then return
|
||||
// collapsed range with editor root element as range container.
|
||||
if (aStartHTOffset == 0 && aEndHTOffset == 0) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
bool isEmpty = false;
|
||||
editor->GetDocumentIsEmpty(&isEmpty);
|
||||
|
@ -1455,8 +1453,10 @@ NS_IMETHODIMP nsHyperTextAccessible::SetTextContents(const nsAString &aText)
|
|||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
|
||||
nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor));
|
||||
NS_ENSURE_STATE(peditor);
|
||||
|
@ -1470,8 +1470,10 @@ nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition)
|
|||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aStartPos, aEndPos);
|
||||
|
@ -1483,8 +1485,10 @@ nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos)
|
|||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aStartPos, aEndPos);
|
||||
|
@ -1496,8 +1500,10 @@ nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos)
|
|||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aStartPos, aEndPos);
|
||||
|
@ -1509,8 +1515,10 @@ nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos)
|
|||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::PasteText(PRInt32 aPosition)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aPosition, aPosition);
|
||||
|
@ -1519,44 +1527,37 @@ nsHyperTextAccessible::PasteText(PRInt32 aPosition)
|
|||
return editor->Paste(nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsHyperTextAccessible::GetEditor() const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEditor);
|
||||
*aEditor = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mContent->HasFlag(NODE_IS_EDITABLE)) {
|
||||
// If we're inside an editable container, then return that container's editor
|
||||
nsCOMPtr<nsIAccessible> ancestor, current = this;
|
||||
while (NS_SUCCEEDED(current->GetParent(getter_AddRefs(ancestor))) && ancestor) {
|
||||
nsRefPtr<nsHyperTextAccessible> ancestorTextAccessible;
|
||||
ancestor->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
|
||||
getter_AddRefs(ancestorTextAccessible));
|
||||
if (ancestorTextAccessible) {
|
||||
nsAccessible* ancestor = Parent();
|
||||
while (ancestor) {
|
||||
nsHyperTextAccessible* hyperText = ancestor->AsHyperText();
|
||||
if (hyperText) {
|
||||
// Recursion will stop at container doc because it has its own impl
|
||||
// of GetAssociatedEditor()
|
||||
return ancestorTextAccessible->GetAssociatedEditor(aEditor);
|
||||
// of GetEditor()
|
||||
return hyperText->GetEditor();
|
||||
}
|
||||
current = ancestor;
|
||||
|
||||
ancestor = ancestor->Parent();
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mContent);
|
||||
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem));
|
||||
if (!editingSession)
|
||||
return NS_OK; // No editing session interface
|
||||
|
||||
NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
|
||||
nsIDocument* docNode = mDoc->GetDocumentNode();
|
||||
NS_ENSURE_TRUE(docNode, NS_ERROR_FAILURE);
|
||||
return nsnull; // No editing session interface
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
return editingSession->GetEditorForWindow(docNode->GetWindow(), aEditor);
|
||||
nsIDocument* docNode = mDoc->GetDocumentNode();
|
||||
editingSession->GetEditorForWindow(docNode->GetWindow(),
|
||||
getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1770,8 +1771,7 @@ nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
|
|||
|
||||
nsCOMPtr<nsINode> startNode = GetNode();
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
nsCOMPtr<nsIDOMElement> editorRoot;
|
||||
editor->GetRootElement(getter_AddRefs(editorRoot));
|
||||
|
|
|
@ -264,6 +264,14 @@ public:
|
|||
return GetChildAt(GetChildIndexAtOffset(aOffset));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EditableTextAccessible
|
||||
|
||||
/**
|
||||
* Return the editor associated with the accessible.
|
||||
*/
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
protected:
|
||||
// nsHyperTextAccessible
|
||||
|
||||
|
|
|
@ -273,8 +273,7 @@ nsXFormsEditableAccessible::NativeState()
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_TRUE(editor, state);
|
||||
PRUint32 flags;
|
||||
editor->GetFlags(&flags);
|
||||
|
@ -286,11 +285,14 @@ nsXFormsEditableAccessible::NativeState()
|
|||
return state;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsEditableAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsXFormsEditableAccessible::GetEditor() const
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
|
||||
return sXFormsService->GetEditor(DOMNode, aEditor);
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
sXFormsService->GetEditor(DOMNode, getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -144,8 +144,8 @@ class nsXFormsEditableAccessible : public nsXFormsAccessible
|
|||
public:
|
||||
nsXFormsEditableAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual PRUint64 NativeState();
|
||||
|
|
|
@ -850,14 +850,17 @@ nsXULTextFieldAccessible::CanHaveAnonChildren()
|
|||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsXULTextFieldAccessible::GetEditor() const
|
||||
{
|
||||
*aEditor = nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> inputField = GetInputField();
|
||||
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(inputField));
|
||||
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
|
||||
return editableElt->GetEditor(aEditor);
|
||||
if (!editableElt)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editableElt->GetEditor(getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -260,8 +260,8 @@ public:
|
|||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual void ApplyARIAState(PRUint64* aState);
|
||||
|
|
|
@ -613,9 +613,9 @@ function getNodePrettyName(aNode)
|
|||
function getObjAddress(aObj)
|
||||
{
|
||||
var exp = /native\s*@\s*(0x[a-f0-9]+)/g;
|
||||
var match = exp.exec(aObj.valueOf());
|
||||
var match = exp.exec(aObj.toString());
|
||||
if (match)
|
||||
return match[1];
|
||||
|
||||
return aObj.valueOf();
|
||||
return aObj.toString();
|
||||
}
|
||||
|
|
|
@ -304,12 +304,20 @@ function eventQueue(aEventType)
|
|||
// Start processing of next invoker.
|
||||
invoker = this.getNextInvoker();
|
||||
|
||||
this.setEventHandler(invoker);
|
||||
|
||||
if (gLogger.isEnabled()) {
|
||||
gLogger.logToConsole("Event queue: \n invoke: " + invoker.getID());
|
||||
gLogger.logToDOM("EQ: invoke: " + invoker.getID(), true);
|
||||
}
|
||||
|
||||
this.setEventHandler(invoker);
|
||||
var infoText = "Invoke the '" + invoker.getID() + "' test { ";
|
||||
for (var idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
infoText += this.isEventUnexpected(idx) ? "un" : "";
|
||||
infoText += "expected '" + this.getEventTypeAsString(idx) + "' event; ";
|
||||
}
|
||||
infoText += " }";
|
||||
info(infoText);
|
||||
|
||||
if (invoker.invoke() == INVOKER_ACTION_FAILED) {
|
||||
// Invoker failed to prepare action, fail and finish tests.
|
||||
|
|
|
@ -18,6 +18,7 @@ builtin(include, build/autoconf/lto.m4)dnl
|
|||
builtin(include, build/autoconf/gcc-pr49911.m4)dnl
|
||||
builtin(include, build/autoconf/frameptr.m4)dnl
|
||||
builtin(include, build/autoconf/compiler-opts.m4)dnl
|
||||
builtin(include, build/autoconf/expandlibs.m4)dnl
|
||||
|
||||
MOZ_PROG_CHECKMSYS()
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ pref("browser.homescreenURL", "file:///data/local/homescreen.html,file:///system
|
|||
#endif
|
||||
|
||||
// URL for the dialer application.
|
||||
pref("dom.telephony.app.phone.url", "http://localhost:7777/data/local/apps/dialer/dialer.html");
|
||||
pref("dom.telephony.app.phone.url", "http://localhost:7777/data/local/apps/dialer/dialer.html http://localhost:7777/data/local/apps/homescreen/homescreen.html http://localhost:7777/apps/dialer/dialer.html http://localhost:7777/apps/homescreen/homescreen.html");
|
||||
|
||||
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
|
||||
pref("browser.viewport.scaleRatio", -1);
|
||||
|
|
|
@ -66,7 +66,7 @@ pref("extensions.getAddons.cache.enabled", true);
|
|||
pref("extensions.getAddons.maxResults", 15);
|
||||
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%");
|
||||
pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%");
|
||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%&platform=%OS%&appver=%VERSION%");
|
||||
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%?src=firefox");
|
||||
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%/%COMPATIBILITY_MODE%");
|
||||
|
||||
|
@ -214,6 +214,7 @@ pref("app.update.service.enabled", true);
|
|||
//
|
||||
pref("extensions.update.enabled", true);
|
||||
pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
|
||||
pref("extensions.update.interval", 86400); // Check for updates to Extensions and
|
||||
// Themes every day
|
||||
// Non-symmetric (not shared by extensions) extension-specific [update] preferences
|
||||
|
@ -1041,6 +1042,9 @@ pref("devtools.debugger.enabled", false);
|
|||
// The default Debugger UI height
|
||||
pref("devtools.debugger.ui.height", 250);
|
||||
|
||||
// Disable remote debugging protocol logging
|
||||
pref("devtools.debugger.log", false);
|
||||
|
||||
// Enable the style inspector
|
||||
pref("devtools.styleinspector.enabled", true);
|
||||
|
||||
|
|
|
@ -40,10 +40,12 @@ let gDropTargetShim = {
|
|||
* @param aEvent The 'dragstart' event.
|
||||
*/
|
||||
_start: function DropTargetShim_start(aEvent) {
|
||||
gGrid.lock();
|
||||
if (aEvent.target.classList.contains("site")) {
|
||||
gGrid.lock();
|
||||
|
||||
// XXX bug 505521 - Listen for dragover on the document.
|
||||
document.documentElement.addEventListener("dragover", this._dragover, false);
|
||||
// XXX bug 505521 - Listen for dragover on the document.
|
||||
document.documentElement.addEventListener("dragover", this._dragover, false);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -850,7 +850,7 @@ nsContextMenu.prototype = {
|
|||
let uri = makeURI(this.mediaURL);
|
||||
let url = uri.QueryInterface(Ci.nsIURL);
|
||||
if (url.fileBaseName)
|
||||
name = url.fileBaseName + ".jpg";
|
||||
name = decodeURI(url.fileBaseName) + ".jpg";
|
||||
} catch (e) { }
|
||||
if (!name)
|
||||
name = "snapshot.jpg";
|
||||
|
|
|
@ -20,7 +20,9 @@ _BROWSER_FILES = \
|
|||
browser_newtab_reset.js \
|
||||
browser_newtab_tabsync.js \
|
||||
browser_newtab_unpin.js \
|
||||
browser_newtab_bug722273.js \
|
||||
browser_newtab_bug723102.js \
|
||||
browser_newtab_bug723121.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const NOW = Date.now() * 1000;
|
||||
const URL = "http://fake-site.com/";
|
||||
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/NewTabUtils.jsm", tmp);
|
||||
Cc["@mozilla.org/moz/jssubscript-loader;1"]
|
||||
.getService(Ci.mozIJSSubScriptLoader)
|
||||
.loadSubScript("chrome://browser/content/sanitize.js", tmp);
|
||||
|
||||
let {NewTabUtils, Sanitizer} = tmp;
|
||||
|
||||
let bhist = Cc["@mozilla.org/browser/global-history;2"]
|
||||
.getService(Ci.nsIBrowserHistory);
|
||||
|
||||
function runTests() {
|
||||
clearHistory();
|
||||
fillHistory();
|
||||
yield addNewTabPageTab();
|
||||
|
||||
is(cells[0].site.url, URL, "first site is our fake site");
|
||||
|
||||
let page = {
|
||||
update: function () {
|
||||
executeSoon(TestRunner.next);
|
||||
},
|
||||
|
||||
observe: function () {}
|
||||
};
|
||||
|
||||
NewTabUtils.allPages.register(page);
|
||||
yield clearHistory();
|
||||
|
||||
NewTabUtils.allPages.unregister(page);
|
||||
ok(!cells[0].site, "the fake site is gone");
|
||||
}
|
||||
|
||||
function fillHistory() {
|
||||
let uri = makeURI(URL);
|
||||
for (let i = 59; i > 0; i--)
|
||||
bhist.addPageWithDetails(uri, "fake site", NOW - i * 60 * 1000000);
|
||||
}
|
||||
|
||||
function clearHistory() {
|
||||
let s = new Sanitizer();
|
||||
s.prefDomain = "privacy.cpd.";
|
||||
|
||||
let prefs = gPrefService.getBranch(s.prefDomain);
|
||||
prefs.setBoolPref("history", true);
|
||||
prefs.setBoolPref("downloads", false);
|
||||
prefs.setBoolPref("cache", false);
|
||||
prefs.setBoolPref("cookies", false);
|
||||
prefs.setBoolPref("formdata", false);
|
||||
prefs.setBoolPref("offlineApps", false);
|
||||
prefs.setBoolPref("passwords", false);
|
||||
prefs.setBoolPref("sessions", false);
|
||||
prefs.setBoolPref("siteSettings", false);
|
||||
|
||||
s.sanitize();
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function runTests() {
|
||||
setLinks("0,1,2,3,4,5,6,7,8");
|
||||
setPinnedLinks("");
|
||||
|
||||
yield addNewTabPageTab();
|
||||
checkGridLocked(false, "grid is unlocked");
|
||||
|
||||
let cell = cells[0].node;
|
||||
let site = cells[0].site.node;
|
||||
|
||||
sendDragEvent(site, "dragstart");
|
||||
checkGridLocked(true, "grid is now locked");
|
||||
|
||||
sendDragEvent(site, "dragend");
|
||||
checkGridLocked(false, "grid isn't locked anymore");
|
||||
|
||||
sendDragEvent(cell, "dragstart");
|
||||
checkGridLocked(false, "grid isn't locked - dragstart was ignored");
|
||||
}
|
||||
|
||||
function checkGridLocked(aLocked, aMessage) {
|
||||
is(cw.gGrid.node.hasAttribute("locked"), aLocked, aMessage);
|
||||
}
|
||||
|
||||
function sendDragEvent(aNode, aType) {
|
||||
let ifaceReq = cw.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let windowUtils = ifaceReq.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let dataTransfer = {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
setDragImage: function () null,
|
||||
getData: function () "about:blank"
|
||||
};
|
||||
|
||||
let event = cw.document.createEvent("DragEvents");
|
||||
event.initDragEvent(aType, true, true, cw, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
|
||||
windowUtils.dispatchDOMEventViaPresShell(aNode, event, true);
|
||||
}
|
|
@ -129,10 +129,11 @@ function addNewTabPageTab() {
|
|||
cw = browser.contentWindow;
|
||||
|
||||
if (NewTabUtils.allPages.enabled) {
|
||||
cells = cw.gGrid.cells;
|
||||
|
||||
// Continue when the link cache has been populated.
|
||||
NewTabUtils.links.populateCache(TestRunner.next);
|
||||
NewTabUtils.links.populateCache(function () {
|
||||
cells = cw.gGrid.cells;
|
||||
executeSoon(TestRunner.next);
|
||||
});
|
||||
} else {
|
||||
TestRunner.next();
|
||||
}
|
||||
|
@ -246,6 +247,8 @@ function unpinCell(aCell) {
|
|||
*/
|
||||
function simulateDrop(aDropTarget, aDragSource) {
|
||||
let event = {
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
dataTransfer: {
|
||||
mozUserCancelled: false,
|
||||
setData: function () null,
|
||||
|
|
|
@ -47,20 +47,6 @@
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#technicalContent > h2, #expertContent > h2 {
|
||||
cursor: pointer;
|
||||
-moz-padding-start: 20px;
|
||||
position: relative;
|
||||
left: -20px;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent > h2,
|
||||
body[dir="rtl"] #expertContent > h2 {
|
||||
left: auto;
|
||||
right: -20px;
|
||||
}
|
||||
|
||||
div[collapsed] > p,
|
||||
div[collapsed] > div {
|
||||
.expander[collapsed] + * {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -260,18 +260,18 @@
|
|||
|
||||
<!-- The following sections can be unhidden by default by setting the
|
||||
"browser.xul.error_pages.expert_bad_cert" pref to true -->
|
||||
<div id="technicalContent" collapsed="true">
|
||||
<h2 onclick="toggle('technicalContent');" id="technicalContentHeading">&certerror.technical.heading;</h2>
|
||||
<p id="technicalContentText"/>
|
||||
</div>
|
||||
<h2 id="technicalContent" class="expander" collapsed="true">
|
||||
<button onclick="toggle('technicalContent');">&certerror.technical.heading;</button>
|
||||
</h2>
|
||||
<p id="technicalContentText"/>
|
||||
|
||||
<div id="expertContent" collapsed="true">
|
||||
<h2 onclick="toggle('expertContent');" id="expertContentHeading">&certerror.expert.heading;</h2>
|
||||
<div>
|
||||
<p>&certerror.expert.content;</p>
|
||||
<p>&certerror.expert.contentPara2;</p>
|
||||
<button id='exceptionDialogButton'>&certerror.addException.label;</button>
|
||||
</div>
|
||||
<h2 id="expertContent" class="expander" collapsed="true">
|
||||
<button onclick="toggle('expertContent');">&certerror.expert.heading;</button>
|
||||
</h2>
|
||||
<div>
|
||||
<p>&certerror.expert.content;</p>
|
||||
<p>&certerror.expert.contentPara2;</p>
|
||||
<button id='exceptionDialogButton'>&certerror.addException.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsStringAPI.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsIPrefLocalizedString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace browser {
|
||||
|
@ -200,7 +201,18 @@ AppendDistroSearchDirs(nsIProperties* aDirSvc, nsCOMArray<nsIFile> &array)
|
|||
localePlugins->AppendNative(NS_LITERAL_CSTRING("locale"));
|
||||
|
||||
nsCString locale;
|
||||
rv = prefs->GetCharPref("general.useragent.locale", getter_Copies(locale));
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefString;
|
||||
rv = prefs->GetComplexValue("general.useragent.locale",
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
getter_AddRefs(prefString));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString wLocale;
|
||||
prefString->GetData(getter_Copies(wLocale));
|
||||
CopyUTF16toUTF8(wLocale, locale);
|
||||
} else {
|
||||
rv = prefs->GetCharPref("general.useragent.locale", getter_Copies(locale));
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
nsCOMPtr<nsIFile> curLocalePlugins;
|
||||
|
|
|
@ -43,6 +43,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
DIRS = public src
|
||||
|
||||
TEST_DIRS += tests
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# Needed for preprocessor removal of IE Profile Migrator label - bug 236901
|
||||
|
|
|
@ -65,6 +65,7 @@ var MigrationWizard = {
|
|||
this._source = window.arguments[0];
|
||||
this._migrator = window.arguments[1].QueryInterface(kIMig);
|
||||
this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup);
|
||||
this._skipImportSourcePage = window.arguments[3];
|
||||
|
||||
if (this._autoMigrate) {
|
||||
// Show the "nothing" option in the automigrate case to provide an
|
||||
|
@ -94,7 +95,7 @@ var MigrationWizard = {
|
|||
// Reference to the "From File" radio button
|
||||
var fromfile = null;
|
||||
|
||||
//XXXquark This function is called before init, so check for bookmarks here
|
||||
// init is not called when openDialog opens the wizard, so check for bookmarks here.
|
||||
if ("arguments" in window && window.arguments[0] == "bookmarks") {
|
||||
this._bookmarks = true;
|
||||
|
||||
|
@ -151,6 +152,12 @@ var MigrationWizard = {
|
|||
document.getElementById("importBookmarks").hidden = true;
|
||||
document.getElementById("importAll").hidden = true;
|
||||
}
|
||||
|
||||
// Advance to the next page if the caller told us to.
|
||||
if (this._migrator && this._skipImportSourcePage) {
|
||||
this._wiz.advance();
|
||||
this._wiz.canRewind = false;
|
||||
}
|
||||
},
|
||||
|
||||
onImportSourcePageAdvanced: function ()
|
||||
|
|
|
@ -227,6 +227,12 @@ FirefoxProfileMigrator.prototype = {
|
|||
this._replaceBookmarks = true;
|
||||
}
|
||||
|
||||
// Ensure that aProfile is not the current profile.
|
||||
if (this._paths.currentProfile.path === this._sourceProfile.path) {
|
||||
throw new Exception("Source and destination profiles are the same");
|
||||
return;
|
||||
}
|
||||
|
||||
Services.obs.notifyObservers(null, "Migration:Started", null);
|
||||
|
||||
// Reset pending count. If this count becomes 0, "Migration:Ended"
|
||||
|
@ -278,6 +284,11 @@ FirefoxProfileMigrator.prototype = {
|
|||
this._sourceProfile.initWithPath(aProfile);
|
||||
|
||||
let result = 0;
|
||||
|
||||
// Ensure that aProfile is not the current profile.
|
||||
if (this._paths.currentProfile.path === this._sourceProfile.path)
|
||||
return result;
|
||||
|
||||
if (!this._sourceProfile.exists() || !this._sourceProfile.isReadable()) {
|
||||
Cu.reportError("source profile directory doesn't exist or is not readable");
|
||||
return result;
|
||||
|
|
|
@ -16,10 +16,25 @@ function ProfileMigrator() {
|
|||
}
|
||||
|
||||
ProfileMigrator.prototype = {
|
||||
migrate: function PM_migrate(aStartup) {
|
||||
migrate: function PM_migrate(aStartup, aKey) {
|
||||
// By opening the wizard with a supplied migrator, it will automatically
|
||||
// migrate from it.
|
||||
let [key, migrator] = this._getDefaultMigrator();
|
||||
let key = null, migrator = null;
|
||||
let skipImportSourcePage = Cc["@mozilla.org/supports-PRBool;1"]
|
||||
.createInstance(Ci.nsISupportsPRBool);
|
||||
if (aKey) {
|
||||
key = aKey;
|
||||
migrator = this._getMigratorIfSourceExists(key);
|
||||
if (!migrator) {
|
||||
Cu.reportError("Invalid migrator key specified or source does not exist.");
|
||||
return;
|
||||
}
|
||||
// If the migrator was passed to us from the caller, use that migrator
|
||||
// and skip the import source page.
|
||||
skipImportSourcePage.data = true;
|
||||
} else {
|
||||
[key, migrator] = this._getDefaultMigrator();
|
||||
}
|
||||
if (!key)
|
||||
return;
|
||||
|
||||
|
@ -27,6 +42,7 @@ ProfileMigrator.prototype = {
|
|||
params.appendElement(this._toCString(key), false);
|
||||
params.appendElement(migrator, false);
|
||||
params.appendElement(aStartup, false);
|
||||
params.appendElement(skipImportSourcePage, false);
|
||||
|
||||
Services.ww.openWindow(null,
|
||||
"chrome://browser/content/migration/migration.xul",
|
||||
|
@ -43,10 +59,14 @@ ProfileMigrator.prototype = {
|
|||
},
|
||||
|
||||
_getMigratorIfSourceExists: function PM__getMigratorIfSourceExists(aKey) {
|
||||
let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
|
||||
let migrator = Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
|
||||
if (migrator.sourceExists)
|
||||
return migrator;
|
||||
try {
|
||||
let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
|
||||
let migrator = Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
|
||||
if (migrator.sourceExists)
|
||||
return migrator;
|
||||
} catch (ex) {
|
||||
Cu.reportError("Could not get migrator: " + ex);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
|
|
@ -1412,6 +1412,9 @@ nsIEProfileMigrator::CopyFavoritesBatched(bool aReplace)
|
|||
|
||||
// Locate the Links toolbar folder, we want to replace the Personal Toolbar
|
||||
// content with Favorites in this folder.
|
||||
// On versions minor or equal to IE6 the folder name is stored in the
|
||||
// LinksFolderName registry key, but in newer versions it may be just a
|
||||
// Links subfolder inside the default Favorites folder.
|
||||
nsCOMPtr<nsIWindowsRegKey> regKey =
|
||||
do_CreateInstance("@mozilla.org/windows-registry-key;1");
|
||||
if (regKey &&
|
||||
|
@ -1421,9 +1424,14 @@ nsIEProfileMigrator::CopyFavoritesBatched(bool aReplace)
|
|||
nsAutoString linksFolderName;
|
||||
if (NS_SUCCEEDED(regKey->ReadStringValue(
|
||||
NS_LITERAL_STRING("LinksFolderName"),
|
||||
linksFolderName)))
|
||||
linksFolderName))) {
|
||||
personalToolbarFolderName = linksFolderName;
|
||||
}
|
||||
else {
|
||||
personalToolbarFolderName.AssignLiteral("Links");
|
||||
}
|
||||
}
|
||||
|
||||
folder = bookmarksMenuFolderId;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = browser/components/migration/tests
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
XPCSHELL_TESTS = unit
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE NETSCAPE-Bookmark-file-1>
|
||||
<!-- This is an automatically generated file.
|
||||
It will be read and overwritten.
|
||||
DO NOT EDIT! -->
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
|
||||
<TITLE>Bookmarks</TITLE>
|
||||
<H1>Bookmarks Menu</H1>
|
||||
|
||||
<DL><p>
|
||||
<DT><A HREF="http://example.com/" ADD_DATE="1233157972" LAST_MODIFIED="1233157984">example</A>
|
||||
<DT><H3 ADD_DATE="1233157910" LAST_MODIFIED="1233157972" PERSONAL_TOOLBAR_FOLDER="true">Bookmarks Toolbar</H3>
|
||||
<DD>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
|
||||
<DL><p>
|
||||
<DT><A HREF="http://example.com/" ADD_DATE="1233157972" LAST_MODIFIED="1233157984">example</A>
|
||||
</DL><p>
|
||||
</DL><p>
|
|
@ -0,0 +1,28 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const IMIGRATOR = Ci.nsIBrowserProfileMigrator;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
// Initialize profile.
|
||||
let gProfD = do_get_profile();
|
||||
|
||||
function newMigratorFor(aKey) {
|
||||
let cid = "@mozilla.org/profile/migrator;1?app=browser&type=" + aKey;
|
||||
return Cc[cid].createInstance(Ci.nsIBrowserProfileMigrator);
|
||||
}
|
||||
|
||||
let (bookmarkshtml = do_get_file("bookmarks.html")) {
|
||||
bookmarkshtml.copyTo(gProfD, "bookmarks.html");
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
function run_test() {
|
||||
let migrator = newMigratorFor("ie");
|
||||
|
||||
// Sanity check for the source.
|
||||
do_check_true(migrator.sourceExists);
|
||||
|
||||
// Ensure bookmarks migration is available.
|
||||
let availableSources = migrator.getMigrateData("FieldOfFlowers", false);
|
||||
do_check_true((availableSources & IMIGRATOR.BOOKMARKS) > 0);
|
||||
|
||||
// Needed to enforce bookmarks replacing.
|
||||
let startup = {
|
||||
doStartup: function () {},
|
||||
get directory() do_get_profile()
|
||||
}
|
||||
migrator.migrate(IMIGRATOR.BOOKMARKS, startup, "FieldOfFlowers");
|
||||
|
||||
// Check that at least two bookmark have been added to the menu and the
|
||||
// toolbar. The first one comes from bookmarks.html, the others from IE.
|
||||
do_check_true(PlacesUtils.bookmarks
|
||||
.getIdForItemAt(PlacesUtils.bookmarksMenuFolderId, 1) > 0);
|
||||
do_check_true(PlacesUtils.bookmarks
|
||||
.getIdForItemAt(PlacesUtils.toolbarFolderId, 1) > 0);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
[DEFAULT]
|
||||
head = head_migration.js
|
||||
tail =
|
||||
|
||||
[test_IE_bookmarks.js]
|
||||
skip-if = os != "win"
|
|
@ -411,18 +411,20 @@ BrowserGlue.prototype = {
|
|||
|
||||
// For any add-ons that were installed disabled and can be enabled offer
|
||||
// them to the user
|
||||
var win = this.getMostRecentBrowserWindow();
|
||||
var browser = win.gBrowser;
|
||||
var changedIDs = AddonManager.getStartupChanges(AddonManager.STARTUP_CHANGE_INSTALLED);
|
||||
AddonManager.getAddonsByIDs(changedIDs, function(aAddons) {
|
||||
aAddons.forEach(function(aAddon) {
|
||||
// If the add-on isn't user disabled or can't be enabled then skip it
|
||||
if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE))
|
||||
return;
|
||||
if (changedIDs.length > 0) {
|
||||
AddonManager.getAddonsByIDs(changedIDs, function(aAddons) {
|
||||
var win = this.getMostRecentBrowserWindow();
|
||||
var browser = win.gBrowser;
|
||||
aAddons.forEach(function(aAddon) {
|
||||
// If the add-on isn't user disabled or can't be enabled then skip it.
|
||||
if (!aAddon.userDisabled || !(aAddon.permissions & AddonManager.PERM_CAN_ENABLE))
|
||||
return;
|
||||
|
||||
browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id);
|
||||
})
|
||||
});
|
||||
browser.selectedTab = browser.addTab("about:newaddon?id=" + aAddon.id);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
|
||||
Services.telemetry.getHistogramById("FX_KEYWORD_URL_USERSET").add(keywordURLUserSet);
|
||||
|
|
|
@ -657,7 +657,9 @@ PlacesViewBase.prototype = {
|
|||
aPlacesNode._siteURI = aLivemark.siteURI;
|
||||
if (aNewState == Ci.nsINavHistoryContainerResultNode.STATE_OPENED) {
|
||||
aLivemark.registerForUpdates(aPlacesNode, this);
|
||||
// Prioritize the current livemark.
|
||||
aLivemark.reload();
|
||||
PlacesUtils.livemarks.reloadLivemarks();
|
||||
if (shouldInvalidate)
|
||||
this.invalidateContainer(aPlacesNode);
|
||||
}
|
||||
|
@ -900,11 +902,6 @@ PlacesToolbar.prototype = {
|
|||
__proto__: PlacesViewBase.prototype,
|
||||
|
||||
_cbEvents: ["dragstart", "dragover", "dragexit", "dragend", "drop",
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
"mousedown", "mouseup",
|
||||
#endif
|
||||
#endif
|
||||
"mousemove", "mouseover", "mouseout"],
|
||||
|
||||
QueryInterface: function PT_QueryInterface(aIID) {
|
||||
|
@ -1101,16 +1098,6 @@ PlacesToolbar.prototype = {
|
|||
case "mouseout":
|
||||
this._onMouseOut(aEvent);
|
||||
break;
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
case "mouseup":
|
||||
this._onMouseUp(aEvent);
|
||||
break;
|
||||
case "mousedown":
|
||||
this._onMouseDown(aEvent);
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
case "popupshowing":
|
||||
this._onPopupShowing(aEvent);
|
||||
break;
|
||||
|
@ -1538,14 +1525,6 @@ PlacesToolbar.prototype = {
|
|||
draggedElt.getAttribute("type") == "menu") {
|
||||
// If the drag gesture on a container is toward down we open instead
|
||||
// of dragging.
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
if (this._mouseDownTimer) {
|
||||
this._mouseDownTimer.cancel();
|
||||
this._mouseDownTimer = null;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
let translateY = this._cachedMouseMoveEvent.clientY - aEvent.clientY;
|
||||
let translateX = this._cachedMouseMoveEvent.clientX - aEvent.clientX;
|
||||
if ((translateY) >= Math.abs(translateX/2)) {
|
||||
|
@ -1718,47 +1697,6 @@ PlacesToolbar.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#ifndef XP_MACOSX
|
||||
_onMouseDown: function PT__onMouseDown(aEvent) {
|
||||
let target = aEvent.target;
|
||||
if (aEvent.button == 0 &&
|
||||
target.localName == "toolbarbutton" &&
|
||||
target.getAttribute("type") == "menu") {
|
||||
this._allowPopupShowing = false;
|
||||
// On Linux we can open the popup only after a delay.
|
||||
// Indeed as soon as the menupopup opens we are unable to start a
|
||||
// drag aEvent. See bug 500081 for details.
|
||||
this._mouseDownTimer = Cc["@mozilla.org/timer;1"].
|
||||
createInstance(Ci.nsITimer);
|
||||
let callback = {
|
||||
_self: this,
|
||||
_target: target,
|
||||
notify: function(timer) {
|
||||
this._target.open = true;
|
||||
this._mouseDownTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
this._mouseDownTimer.initWithCallback(callback, 300,
|
||||
Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
},
|
||||
|
||||
_onMouseUp: function PT__onMouseUp(aEvent) {
|
||||
if (aEvent.button != 0)
|
||||
return;
|
||||
|
||||
if (this._mouseDownTimer) {
|
||||
// On a click (down/up), we should open the menu popup.
|
||||
this._mouseDownTimer.cancel();
|
||||
this._mouseDownTimer = null;
|
||||
aEvent.target.open = true;
|
||||
}
|
||||
},
|
||||
#endif
|
||||
#endif
|
||||
|
||||
_onMouseMove: function PT__onMouseMove(aEvent) {
|
||||
// Used in dragStart to prevent dragging folders when dragging down.
|
||||
this._cachedMouseMoveEvent = aEvent;
|
||||
|
|
|
@ -90,7 +90,6 @@
|
|||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_feedLocationField"
|
||||
class="uri-element"
|
||||
onblur="gEditItemOverlay.onFeedLocationFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
|
@ -102,7 +101,6 @@
|
|||
observes="paneElementsBroadcaster"/>
|
||||
<textbox id="editBMPanel_siteLocationField"
|
||||
class="uri-element"
|
||||
onblur="gEditItemOverlay.onSiteLocationFieldBlur();"
|
||||
observes="paneElementsBroadcaster"/>
|
||||
</row>
|
||||
|
||||
|
|
|
@ -896,7 +896,9 @@ PlacesTreeView.prototype = {
|
|||
aNode._feedURI = aLivemark.feedURI;
|
||||
if (aNewState == Components.interfaces.nsINavHistoryContainerResultNode.STATE_OPENED) {
|
||||
aLivemark.registerForUpdates(aNode, this);
|
||||
// Prioritize the current livemark.
|
||||
aLivemark.reload();
|
||||
PlacesUtils.livemarks.reloadLivemarks();
|
||||
if (shouldInvalidate)
|
||||
this.invalidateContainer(aNode);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Dave Camp <dcamp@mozilla.com> (original author)
|
||||
* Panos Astithas <past@mozilla.com>
|
||||
* Victor Porof <vporof@mozilla.com>
|
||||
* Mihai Sucan <mihai.sucan@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
|
||||
|
@ -60,9 +61,37 @@ function DebuggerPane(aTab) {
|
|||
this._tab = aTab;
|
||||
this._close = this.close.bind(this);
|
||||
this._debugTab = this.debugTab.bind(this);
|
||||
this.breakpoints = {};
|
||||
}
|
||||
|
||||
DebuggerPane.prototype = {
|
||||
/**
|
||||
* Skip editor breakpoint change events.
|
||||
*
|
||||
* This property tells the source editor event handler to skip handling of
|
||||
* the BREAKPOINT_CHANGE events. This is used when the debugger adds/removes
|
||||
* breakpoints from the editor. Typically, the BREAKPOINT_CHANGE event handler
|
||||
* adds/removes events from the debugger, but when breakpoints are added from
|
||||
* the public debugger API, we need to do things in reverse.
|
||||
*
|
||||
* This implementation relies on the fact that the source editor fires the
|
||||
* BREAKPOINT_CHANGE events synchronously.
|
||||
*
|
||||
* @private
|
||||
* @type boolean
|
||||
*/
|
||||
_skipEditorBreakpointChange: false,
|
||||
|
||||
/**
|
||||
* The list of breakpoints in the debugger as tracked by the current
|
||||
* DebuggerPane instance. This an object where the values are BreakpointActor
|
||||
* objects received from the client, while the keys are actor names, for
|
||||
* example "conn0.breakpoint3".
|
||||
*
|
||||
* @type object
|
||||
*/
|
||||
breakpoints: null,
|
||||
|
||||
/**
|
||||
* Creates and initializes the widgets contained in the debugger UI.
|
||||
*/
|
||||
|
@ -87,11 +116,15 @@ DebuggerPane.prototype = {
|
|||
self.frame.removeEventListener("DOMContentLoaded", initPane, true);
|
||||
// Initialize the source editor.
|
||||
self.frame.contentWindow.editor = self.editor = new SourceEditor();
|
||||
self.frame.contentWindow.updateEditorBreakpoints =
|
||||
self._updateEditorBreakpoints.bind(self);
|
||||
|
||||
let config = {
|
||||
mode: SourceEditor.MODES.JAVASCRIPT,
|
||||
showLineNumbers: true,
|
||||
readOnly: true
|
||||
readOnly: true,
|
||||
showAnnotationRuler: true,
|
||||
showOverviewRuler: true,
|
||||
};
|
||||
|
||||
let editorPlaceholder = self.frame.contentDocument.getElementById("editor");
|
||||
|
@ -107,14 +140,217 @@ DebuggerPane.prototype = {
|
|||
* editor initialization.
|
||||
*/
|
||||
_onEditorLoad: function DP__onEditorLoad() {
|
||||
this.editor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
this._onEditorBreakpointChange.bind(this));
|
||||
// Connect to the debugger server.
|
||||
this.connect();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for breakpoint changes that happen in the editor. This
|
||||
* function syncs the breakpoint changes in the editor to those in the
|
||||
* debugger.
|
||||
*
|
||||
* @private
|
||||
* @param object aEvent
|
||||
* The SourceEditor.EVENTS.BREAKPOINT_CHANGE event object.
|
||||
*/
|
||||
_onEditorBreakpointChange: function DP__onEditorBreakpointChange(aEvent) {
|
||||
if (this._skipEditorBreakpointChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
aEvent.added.forEach(this._onEditorBreakpointAdd, this);
|
||||
aEvent.removed.forEach(this._onEditorBreakpointRemove, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the URL of the selected script in the debugger view.
|
||||
*
|
||||
* @private
|
||||
* @return string
|
||||
* The URL of the selected script.
|
||||
*/
|
||||
_selectedScript: function DP__selectedScript() {
|
||||
return this.debuggerWindow ?
|
||||
this.debuggerWindow.DebuggerView.Scripts.selected : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for new breakpoints that come from the editor.
|
||||
*
|
||||
* @private
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint object coming from the editor.
|
||||
*/
|
||||
_onEditorBreakpointAdd: function DP__onEditorBreakpointAdd(aBreakpoint) {
|
||||
let location = {
|
||||
url: this._selectedScript(),
|
||||
line: aBreakpoint.line + 1,
|
||||
};
|
||||
|
||||
if (location.url) {
|
||||
let callback = function (aClient, aError) {
|
||||
if (aError) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
let result = this.editor.removeBreakpoint(aBreakpoint.line);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}.bind(this);
|
||||
this.addBreakpoint(location, callback, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for breakpoints that are removed from the editor.
|
||||
*
|
||||
* @private
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint object that was removed from the editor.
|
||||
*/
|
||||
_onEditorBreakpointRemove: function DP__onEditorBreakpointRemove(aBreakpoint) {
|
||||
let url = this._selectedScript();
|
||||
let line = aBreakpoint.line + 1;
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
let breakpoint = this.getBreakpoint(url, line);
|
||||
if (breakpoint) {
|
||||
this.removeBreakpoint(breakpoint, null, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the breakpoints in the editor view. This function takes the list of
|
||||
* breakpoints in the debugger and adds them back into the editor view. This
|
||||
* is invoked when the selected script is changed.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_updateEditorBreakpoints: function DP__updateEditorBreakpoints()
|
||||
{
|
||||
let url = this._selectedScript();
|
||||
if (!url) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._skipEditorBreakpointChange = true;
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
if (breakpoint.location.url == url) {
|
||||
this.editor.addBreakpoint(breakpoint.location.line - 1);
|
||||
}
|
||||
}
|
||||
this._skipEditorBreakpointChange = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a breakpoint.
|
||||
*
|
||||
* @param object aLocation
|
||||
* The location where you want the breakpoint. This object must have
|
||||
* two properties:
|
||||
* - url - the URL of the script.
|
||||
* - line - the line number (starting from 1).
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the breakpoint is added. The
|
||||
* callback is invoked with two arguments:
|
||||
* - aBreakpointClient - the BreakpointActor client object, if the
|
||||
* breakpoint has been added successfully.
|
||||
* - aResponseError - if there was any error.
|
||||
* @param boolean [aNoEditorUpdate=false]
|
||||
* Tells if you want to skip editor updates. Typically the editor is
|
||||
* updated to visually indicate that a breakpoint has been added.
|
||||
*/
|
||||
addBreakpoint:
|
||||
function DP_addBreakpoint(aLocation, aCallback, aNoEditorUpdate) {
|
||||
let breakpoint = this.getBreakpoint(aLocation.url, aLocation.line);
|
||||
if (breakpoint) {
|
||||
aCallback && aCallback(breakpoint);
|
||||
return;
|
||||
}
|
||||
|
||||
this.activeThread.setBreakpoint(aLocation, function(aResponse, aBpClient) {
|
||||
if (!aResponse.error) {
|
||||
this.breakpoints[aBpClient.actor] = aBpClient;
|
||||
|
||||
if (!aNoEditorUpdate) {
|
||||
let url = this._selectedScript();
|
||||
if (url == aLocation.url) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
this.editor.addBreakpoint(aLocation.line - 1);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aCallback && aCallback(aBpClient, aResponse.error);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a breakpoint.
|
||||
*
|
||||
* @param object aBreakpoint
|
||||
* The breakpoint you want to remove.
|
||||
* @param function [aCallback]
|
||||
* Optional function to invoke once the breakpoint is removed. The
|
||||
* callback is invoked with one argument: the breakpoint location
|
||||
* object which holds the url and line properties.
|
||||
* @param boolean [aNoEditorUpdate=false]
|
||||
* Tells if you want to skip editor updates. Typically the editor is
|
||||
* updated to visually indicate that a breakpoint has been removed.
|
||||
*/
|
||||
removeBreakpoint:
|
||||
function DP_removeBreakpoint(aBreakpoint, aCallback, aNoEditorUpdate) {
|
||||
if (!(aBreakpoint.actor in this.breakpoints)) {
|
||||
aCallback && aCallback(aBreakpoint.location);
|
||||
return;
|
||||
}
|
||||
|
||||
aBreakpoint.remove(function() {
|
||||
delete this.breakpoints[aBreakpoint.actor];
|
||||
|
||||
if (!aNoEditorUpdate) {
|
||||
let url = this._selectedScript();
|
||||
if (url == aBreakpoint.location.url) {
|
||||
this._skipEditorBreakpointChange = true;
|
||||
this.editor.removeBreakpoint(aBreakpoint.location.line - 1);
|
||||
this._skipEditorBreakpointChange = false;
|
||||
}
|
||||
}
|
||||
|
||||
aCallback && aCallback(aBreakpoint.location);
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the breakpoint object at the given location.
|
||||
*
|
||||
* @param string aUrl
|
||||
* The URL of where the breakpoint is.
|
||||
* @param number aLine
|
||||
* The line number where the breakpoint is.
|
||||
* @return object
|
||||
* The BreakpointActor object.
|
||||
*/
|
||||
getBreakpoint: function DP_getBreakpoint(aUrl, aLine) {
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
if (breakpoint.location.url == aUrl && breakpoint.location.line == aLine) {
|
||||
return breakpoint;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the debugger UI removing child nodes and event listeners.
|
||||
*/
|
||||
close: function DP_close() {
|
||||
for each (let breakpoint in this.breakpoints) {
|
||||
this.removeBreakpoint(breakpoint);
|
||||
}
|
||||
|
||||
if (this._tab) {
|
||||
this._tab._scriptDebugger = null;
|
||||
this._tab = null;
|
||||
|
@ -192,7 +428,7 @@ DebuggerPane.prototype = {
|
|||
},
|
||||
|
||||
get debuggerWindow() {
|
||||
return this.frame.contentWindow;
|
||||
return this.frame ? this.frame.contentWindow : null;
|
||||
},
|
||||
|
||||
get debuggerClient() {
|
||||
|
@ -340,6 +576,7 @@ DebuggerUI.prototype = {
|
|||
script.text = aSourceText;
|
||||
script.contentType = aContentType;
|
||||
elt.setUserData("sourceScript", script, null);
|
||||
dbg._updateEditorBreakpoints();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Victor Porof <vporof@mozilla.com> (original author)
|
||||
* Mihai Sucan <mihai.sucan@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
|
||||
|
@ -199,7 +200,6 @@ DebuggerView.Stackframes = {
|
|||
|
||||
// the list item wasn't found in the stackframe container
|
||||
if (!frame) {
|
||||
dump("The frame list item wasn't found in the stackframes container.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -356,7 +356,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the element was created successfully
|
||||
if (!element) {
|
||||
dump("The debugger scope container wasn't created properly: " + aId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -398,7 +397,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the element was created successfully
|
||||
if (!element) {
|
||||
dump("The debugger variable container wasn't created properly: " + aId);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -466,7 +464,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the info node exists
|
||||
if (!info) {
|
||||
dump("Could not set the grip for the corresponding variable: " + aVar.id);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -569,7 +566,6 @@ DebuggerView.Properties = {
|
|||
|
||||
// make sure the element was created successfully
|
||||
if (!element) {
|
||||
dump("The debugger property container wasn't created properly.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -710,11 +706,9 @@ DebuggerView.Properties = {
|
|||
_createPropertyElement: function DVP__createPropertyElement(aName, aId, aClass, aParent) {
|
||||
// make sure we don't duplicate anything and the parent exists
|
||||
if (document.getElementById(aId)) {
|
||||
dump("Duplicating a property element id is not allowed.");
|
||||
return null;
|
||||
}
|
||||
if (!aParent) {
|
||||
dump("A property element must have a valid parent node specified.");
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1127,6 +1121,15 @@ DebuggerView.Scripts = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the URL of the selected script.
|
||||
* @return string|null
|
||||
*/
|
||||
get selected() {
|
||||
return this._scripts.selectedItem ?
|
||||
this._scripts.selectedItem.value : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a script to the scripts container.
|
||||
* If the script already exists (was previously added), null is returned.
|
||||
|
|
|
@ -78,7 +78,8 @@ function startDebuggingTab(aClient, aTabGrip)
|
|||
gTabClient = aTabClient;
|
||||
gClient.attachThread(aResponse.threadActor, function(aResponse, aThreadClient) {
|
||||
if (!aThreadClient) {
|
||||
dump("Couldn't attach to thread: "+aResponse.error+"\n");
|
||||
Components.utils.reportError("Couldn't attach to thread: " +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
ThreadState.connect(aThreadClient, function() {
|
||||
|
@ -612,6 +613,7 @@ var SourceScripts = {
|
|||
window.editor.setText(DebuggerView.getStr("loadingText"));
|
||||
} else {
|
||||
window.editor.setText(aScript.text);
|
||||
window.updateEditorBreakpoints();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_dbg_update-editor-mode.js \
|
||||
browser_dbg_select-line.js \
|
||||
browser_dbg_clean-exit.js \
|
||||
browser_dbg_bug723069_editor-breakpoints.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,274 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723069: test the debugger breakpoint API and connection to the source
|
||||
* editor.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "browser_dbg_script-switching.html";
|
||||
|
||||
let gPane = null;
|
||||
let gTab = null;
|
||||
let gDebuggee = null;
|
||||
let gDebugger = null;
|
||||
let gScripts = null;
|
||||
let gEditor = null;
|
||||
let gBreakpoints = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||
let SourceEditor = tempScope.SourceEditor;
|
||||
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
gPane.activeThread.addOneTimeListener("scriptsadded", function() {
|
||||
Services.tm.currentThread.dispatch({ run: onScriptsAdded }, 0);
|
||||
});
|
||||
gDebuggee.firstCall();
|
||||
});
|
||||
|
||||
function onScriptsAdded()
|
||||
{
|
||||
gScripts = gDebugger.DebuggerView.Scripts;
|
||||
|
||||
is(gDebugger.StackFrames.activeThread.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
|
||||
is(gScripts._scripts.itemCount, 2, "Found the expected number of scripts.");
|
||||
|
||||
gEditor = gDebugger.editor;
|
||||
|
||||
isnot(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The correct script was loaded initially.");
|
||||
isnot(gScripts.selected, gScripts.scriptLocations()[0],
|
||||
"the correct sccript is selected");
|
||||
|
||||
gBreakpoints = gPane.breakpoints;
|
||||
is(Object.keys(gBreakpoints), 0, "no breakpoints");
|
||||
ok(!gPane.getBreakpoint("foo", 3), "getBreakpoint('foo', 3) returns falsey");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0, "no breakpoints in the editor");
|
||||
|
||||
|
||||
info("add the first breakpoint");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddFirst);
|
||||
let location = {url: gScripts.selected, line: 6};
|
||||
executeSoon(function() {
|
||||
gPane.addBreakpoint(location, onBreakpointAddFirst);
|
||||
});
|
||||
}
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
let editorBreakpointChanges = 0;
|
||||
|
||||
function onEditorBreakpointAddFirst(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint1 added to the editor");
|
||||
is(aEvent.added.length, 1, "one breakpoint added to the editor");
|
||||
is(aEvent.removed.length, 0, "no breakpoint was removed from the editor");
|
||||
is(aEvent.added[0].line, 5, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onBreakpointAddFirst(aBreakpointClient, aResponseError)
|
||||
{
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient, "breakpoint1 added, client received");
|
||||
ok(!aResponseError, "breakpoint1 added without errors");
|
||||
is(aBreakpointClient.location.url, gScripts.selected,
|
||||
"breakpoint1 client url is correct");
|
||||
is(aBreakpointClient.location.line, 6,
|
||||
"breakpoint1 client line is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint1 client found in the list of debugger breakpoints");
|
||||
is(Object.keys(gBreakpoints).length, 1,
|
||||
"the list of debugger breakpoints holds only one breakpoint");
|
||||
is(gPane.getBreakpoint(gScripts.selected, 6), aBreakpointClient,
|
||||
"getBreakpoint(selectedScript, 2) returns the correct breakpoint");
|
||||
|
||||
info("remove the first breakpoint");
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveFirst);
|
||||
gPane.removeBreakpoint(aBreakpointClient, onBreakpointRemoveFirst);
|
||||
});
|
||||
}
|
||||
|
||||
function onBreakpointRemoveFirst(aLocation)
|
||||
{
|
||||
breakpointsRemoved++;
|
||||
|
||||
ok(aLocation, "breakpoint1 removed");
|
||||
is(aLocation.url, gScripts.selected, "breakpoint1 remove: url is correct");
|
||||
is(aLocation.line, 6, "breakpoint1 remove: line is correct");
|
||||
|
||||
executeSoon(testBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveFirst(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveFirst);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint1 removed from the editor");
|
||||
is(aEvent.added.length, 0, "no breakpoint was added to the editor");
|
||||
is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
|
||||
is(aEvent.removed[0].line, 5, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function testBreakpointAddBackground()
|
||||
{
|
||||
info("add a breakpoint to the second script which is not selected");
|
||||
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoints in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.selected, 6),
|
||||
"getBreakpoint(selectedScript, 6) returns no breakpoint");
|
||||
|
||||
let script0 = gScripts.scriptLocations()[0];
|
||||
isnot(script0, gScripts.selected,
|
||||
"first script location is not the currently selected script");
|
||||
|
||||
let location = {url: script0, line: 5};
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddBackgroundTrap);
|
||||
gPane.addBreakpoint(location, onBreakpointAddBackground);
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddBackgroundTrap(aEvent)
|
||||
{
|
||||
// trap listener: no breakpoint must be added to the editor when a breakpoint
|
||||
// is added to a script that is not currently selected.
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddBackgroundTrap);
|
||||
editorBreakpointChanges++;
|
||||
ok(false, "breakpoint2 must not be added to the editor");
|
||||
}
|
||||
|
||||
function onBreakpointAddBackground(aBreakpointClient, aResponseError)
|
||||
{
|
||||
breakpointsAdded++;
|
||||
|
||||
ok(aBreakpointClient, "breakpoint2 added, client received");
|
||||
ok(!aResponseError, "breakpoint2 added without errors");
|
||||
is(aBreakpointClient.location.url, gScripts.scriptLocations()[0],
|
||||
"breakpoint2 client url is correct");
|
||||
is(aBreakpointClient.location.line, 5,
|
||||
"breakpoint2 client line is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
ok(aBreakpointClient.actor in gBreakpoints,
|
||||
"breakpoint2 client found in the list of debugger breakpoints");
|
||||
is(Object.keys(gBreakpoints).length, 1, "one breakpoint in the debugger");
|
||||
is(gPane.getBreakpoint(gScripts.scriptLocations()[0], 5), aBreakpointClient,
|
||||
"getBreakpoint(scriptLocations[0], 5) returns the correct breakpoint");
|
||||
|
||||
// remove the trap listener
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddBackgroundTrap);
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddSwitch);
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
|
||||
onEditorTextChanged);
|
||||
|
||||
info("switch to the second script");
|
||||
|
||||
gScripts._scripts.selectedIndex = 0;
|
||||
gDebugger.SourceScripts.onChange({ target: gScripts._scripts });
|
||||
});
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddSwitch(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointAddSwitch);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint2 added to the editor");
|
||||
is(aEvent.added.length, 1, "one breakpoint added to the editor");
|
||||
is(aEvent.removed.length, 0, "no breakpoint was removed from the editor");
|
||||
is(aEvent.added[0].line, 4, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onEditorTextChanged()
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
|
||||
onEditorTextChanged);
|
||||
|
||||
is(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The second script is no longer displayed.");
|
||||
|
||||
isnot(gEditor.getText().indexOf("firstCall"), -1,
|
||||
"The first script is displayed.");
|
||||
|
||||
executeSoon(function() {
|
||||
info("remove the second breakpoint using the mouse");
|
||||
|
||||
gEditor.addEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveSecond);
|
||||
|
||||
let testWin = gEditor.editorElement.ownerDocument.defaultView;
|
||||
EventUtils.synthesizeMouse(gEditor.editorElement, 10, 70, {}, testWin);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveSecond(aEvent)
|
||||
{
|
||||
gEditor.removeEventListener(SourceEditor.EVENTS.BREAKPOINT_CHANGE,
|
||||
onEditorBreakpointRemoveSecond);
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent, "breakpoint2 removed from the editor");
|
||||
is(aEvent.added.length, 0, "no breakpoint was added to the editor");
|
||||
is(aEvent.removed.length, 1, "one breakpoint was removed from the editor");
|
||||
is(aEvent.removed[0].line, 4, "editor breakpoint line is correct");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0, "editor.getBreakpoints().length is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
gDebugger.StackFrames.activeThread.resume(finish);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(Object.keys(gBreakpoints).length, 0, "no breakpoint in the debugger");
|
||||
ok(!gPane.getBreakpoint(gScripts.scriptLocations()[0], 5),
|
||||
"getBreakpoint(scriptLocations[0], 5) returns no breakpoint");
|
||||
|
||||
removeTab(gTab);
|
||||
is(breakpointsAdded, 2, "correct number of breakpoints have been added");
|
||||
is(breakpointsRemoved, 1, "correct number of breakpoints have been removed");
|
||||
is(editorBreakpointChanges, 4, "correct number of editor breakpoint changes");
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gScripts = null;
|
||||
gEditor = null;
|
||||
gBreakpoints = null;
|
||||
});
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
||||
|
@ -15,7 +14,6 @@ const DEBUGGER_TAB_URL = EXAMPLE_URL + "browser_dbg_debuggerstatement.html";
|
|||
function test() {
|
||||
debug_tab_pane(DEBUGGER_TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -29,12 +27,16 @@ function testCleanExit() {
|
|||
is(gDebugger.StackFrames.activeThread.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
|
||||
gPane._client.addOneTimeListener("tabDetached", function () {
|
||||
finish();
|
||||
});
|
||||
removeTab(gTab);
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -55,10 +55,17 @@ function testLocationChange()
|
|||
gPane._client.addOneTimeListener("tabAttached", function(aEvent, aPacket) {
|
||||
ok(true, "Successfully reattached to the tab again.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
content.location = TAB1_URL;
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test() {
|
||||
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -63,8 +61,7 @@ function testResume() {
|
|||
is(button.label, gDebugger.DebuggerView.getStr("pauseLabel"),
|
||||
"Button label should be pause when running.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
|
@ -72,3 +69,9 @@ function testResume() {
|
|||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
});
|
||||
|
|
|
@ -134,9 +134,15 @@ function resumeAndFinish() {
|
|||
is(vs._scripts.itemCount, 6,
|
||||
"Got too many script items in the list!");
|
||||
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -116,16 +116,19 @@ function testSimpleCall() {
|
|||
ok(!testScope.expanded,
|
||||
"Clicking again the testScope tilte should collapse it.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -118,16 +118,19 @@ function testSimpleCall() {
|
|||
is(gDebugger.DebuggerView.Properties._vars.childNodes.length, 4,
|
||||
"The scope should have been removed from the parent container tree.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -73,16 +73,19 @@ function testSimpleCall() {
|
|||
is(testScope.querySelector(".details").childNodes.length, 0,
|
||||
"The var should have been removed from the parent container tree.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -81,16 +81,19 @@ function testSimpleCall() {
|
|||
is(testScope.querySelector(".details").childNodes.length, 0,
|
||||
"The var should have been removed from the parent container tree.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -117,17 +117,19 @@ function testSimpleCall() {
|
|||
is(localVar5.querySelector(".info").textContent, "[object Object]",
|
||||
"The grip information for the localVar5 wasn't set correctly.");
|
||||
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -10,14 +10,12 @@ const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -87,10 +85,16 @@ function resumeAndFinish() {
|
|||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -10,14 +10,12 @@ const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
|
|||
|
||||
var gPane = null;
|
||||
var gTab = null;
|
||||
var gDebuggee = null;
|
||||
var gDebugger = null;
|
||||
|
||||
function test()
|
||||
{
|
||||
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPane = aPane;
|
||||
gDebugger = gPane.debuggerWindow;
|
||||
|
||||
|
@ -103,10 +101,16 @@ function resumeAndFinish() {
|
|||
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"Should have no frames.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -103,6 +103,13 @@ function testSwitchRunning()
|
|||
ok(gDebugger.editor.getText().search(/firstCall/) == -1,
|
||||
"The first script is no longer displayed.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -68,14 +68,22 @@ function testSelectLine() {
|
|||
"The correct line is selected.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Scroll all the way down to ensure stackframe-3 is visible.
|
||||
let stackframes = gDebugger.document.getElementById("stackframes");
|
||||
stackframes.scrollTop = stackframes.scrollHeight;
|
||||
|
||||
// Click the oldest stack frame.
|
||||
let frames = gDebugger.DebuggerView.Stackframes._frames;
|
||||
is(frames.querySelectorAll(".dbg-stackframe").length, 4,
|
||||
"Should have four frames.");
|
||||
|
||||
let element = gDebugger.document.getElementById("stackframe-3");
|
||||
isnot(element, null, "Found the third stack frame.");
|
||||
EventUtils.synthesizeMouseAtCenter(element, {}, gDebugger);
|
||||
});
|
||||
}}, 0);
|
||||
|
@ -83,3 +91,11 @@ function testSelectLine() {
|
|||
|
||||
gDebuggee.firstCall();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -36,16 +36,19 @@ function testSimpleCall() {
|
|||
is(childNodes.length, frames.querySelectorAll(".dbg-stackframe").length,
|
||||
"All children should be frames.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.simpleCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -67,17 +67,19 @@ function testEvalCall() {
|
|||
ok(!frames.querySelector("#stackframe-1").classList.contains("selected"),
|
||||
"Second frame should not be selected after click inside the first frame.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}}, 0);
|
||||
});
|
||||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -47,7 +47,9 @@ function testRecurse() {
|
|||
is(frames.querySelectorAll(".dbg-stackframe").length, recurseLimit,
|
||||
"Should have reached the recurse limit.");
|
||||
|
||||
resumeAndFinish();
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
});
|
||||
|
||||
frames.scrollTop = frames.scrollHeight;
|
||||
|
@ -60,9 +62,10 @@ function testRecurse() {
|
|||
gDebuggee.recurse();
|
||||
}
|
||||
|
||||
function resumeAndFinish() {
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -48,8 +48,7 @@ function testEvalCallResume() {
|
|||
is(frames.querySelectorAll(".empty").length, 1,
|
||||
"Should have the empty list explanation.");
|
||||
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
|
||||
gPane.activeThread.resume();
|
||||
|
@ -58,3 +57,11 @@ function testEvalCallResume() {
|
|||
|
||||
gDebuggee.evalCall();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
|
@ -72,7 +72,15 @@ function testSwitchPaused()
|
|||
"Found the expected editor mode.");
|
||||
|
||||
gDebugger.StackFrames.activeThread.resume(function() {
|
||||
removeTab(gTab);
|
||||
finish();
|
||||
closeDebuggerAndFinish(gTab);
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
removeTab(gTab);
|
||||
gPane = null;
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gDebugger = null;
|
||||
gScripts = null;
|
||||
});
|
||||
|
|
|
@ -49,6 +49,14 @@ function removeTab(aTab) {
|
|||
gBrowser.removeTab(aTab);
|
||||
}
|
||||
|
||||
function closeDebuggerAndFinish(aTab) {
|
||||
DebuggerUI.aWindow.addEventListener("Debugger:Shutdown", function cleanup() {
|
||||
DebuggerUI.aWindow.removeEventListener("Debugger:Shutdown", cleanup, false);
|
||||
finish();
|
||||
}, false);
|
||||
DebuggerUI.getDebugger(aTab).close();
|
||||
}
|
||||
|
||||
function get_tab_actor_for_url(aClient, aURL, aCallback) {
|
||||
aClient.listTabs(function(aResponse) {
|
||||
for each (let tab in aResponse.tabs) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Mihai Sucan <mihai.sucan@gmail.com> (original author)
|
||||
* Kenny Heaton <kennyheaton@gmail.com>
|
||||
* Spyros Livathinos <livathinos.spyros@gmail.com>
|
||||
* Allen Eubank <adeubank@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
|
||||
|
@ -124,6 +125,18 @@ const DEFAULT_KEYBINDINGS = [
|
|||
code: Ci.nsIDOMKeyEvent.DOM_VK_TAB,
|
||||
shift: true,
|
||||
},
|
||||
{
|
||||
action: "Move Lines Up",
|
||||
code: Ci.nsIDOMKeyEvent.DOM_VK_UP,
|
||||
ctrl: Services.appinfo.OS == "Darwin",
|
||||
alt: true,
|
||||
},
|
||||
{
|
||||
action: "Move Lines Down",
|
||||
code: Ci.nsIDOMKeyEvent.DOM_VK_DOWN,
|
||||
ctrl: Services.appinfo.OS == "Darwin",
|
||||
alt: true,
|
||||
},
|
||||
];
|
||||
|
||||
var EXPORTED_SYMBOLS = ["SourceEditor"];
|
||||
|
@ -367,6 +380,7 @@ SourceEditor.prototype = {
|
|||
"Find Next Occurrence": [this.ui.findNext, this.ui],
|
||||
"Find Previous Occurrence": [this.ui.findPrevious, this.ui],
|
||||
"Goto Line...": [this.ui.gotoLine, this.ui],
|
||||
"Move Lines Down": [this._moveLines, this],
|
||||
};
|
||||
|
||||
for (let name in actions) {
|
||||
|
@ -374,9 +388,17 @@ SourceEditor.prototype = {
|
|||
this._view.setAction(name, action[0].bind(action[1]));
|
||||
}
|
||||
|
||||
this._view.setAction("Move Lines Up", this._moveLines.bind(this, true));
|
||||
|
||||
let keys = (config.keys || []).concat(DEFAULT_KEYBINDINGS);
|
||||
keys.forEach(function(aKey) {
|
||||
let binding = new KeyBinding(aKey.code, aKey.accel, aKey.shift, aKey.alt);
|
||||
// In Orion mod1 refers to Cmd on Macs and Ctrl on Windows and Linux.
|
||||
// So, if ctrl is in aKey we use it on Windows and Linux, otherwise
|
||||
// we use aKey.accel for mod1.
|
||||
let mod1 = Services.appinfo.OS != "Darwin" &&
|
||||
"ctrl" in aKey ? aKey.ctrl : aKey.accel;
|
||||
let binding = new KeyBinding(aKey.code, mod1, aKey.shift, aKey.alt,
|
||||
aKey.ctrl);
|
||||
this._view.setKeyBinding(binding, aKey.action);
|
||||
|
||||
if (aKey.callback) {
|
||||
|
@ -578,6 +600,78 @@ SourceEditor.prototype = {
|
|||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Move lines upwards or downwards, relative to the current caret location.
|
||||
*
|
||||
* @private
|
||||
* @param boolean aLineAbove
|
||||
* True if moving lines up, false to move lines down.
|
||||
*/
|
||||
_moveLines: function SE__moveLines(aLineAbove)
|
||||
{
|
||||
if (this.readOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let model = this._model;
|
||||
let selection = this.getSelection();
|
||||
let firstLine = model.getLineAtOffset(selection.start);
|
||||
if (firstLine == 0 && aLineAbove) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let lastLine = model.getLineAtOffset(selection.end);
|
||||
let firstLineStart = model.getLineStart(firstLine);
|
||||
let lastLineStart = model.getLineStart(lastLine);
|
||||
if (selection.start != selection.end && lastLineStart == selection.end) {
|
||||
lastLine--;
|
||||
}
|
||||
if (!aLineAbove && (lastLine + 1) == this.getLineCount()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let lastLineEnd = model.getLineEnd(lastLine, true);
|
||||
let text = this.getText(firstLineStart, lastLineEnd);
|
||||
|
||||
if (aLineAbove) {
|
||||
let aboveLine = firstLine - 1;
|
||||
let aboveLineStart = model.getLineStart(aboveLine);
|
||||
|
||||
this.startCompoundChange();
|
||||
if (lastLine == (this.getLineCount() - 1)) {
|
||||
let delimiterStart = model.getLineEnd(aboveLine);
|
||||
let delimiterEnd = model.getLineEnd(aboveLine, true);
|
||||
let lineDelimiter = this.getText(delimiterStart, delimiterEnd);
|
||||
text += lineDelimiter;
|
||||
this.setText("", firstLineStart - lineDelimiter.length, lastLineEnd);
|
||||
} else {
|
||||
this.setText("", firstLineStart, lastLineEnd);
|
||||
}
|
||||
this.setText(text, aboveLineStart, aboveLineStart);
|
||||
this.endCompoundChange();
|
||||
this.setSelection(aboveLineStart, aboveLineStart + text.length);
|
||||
} else {
|
||||
let belowLine = lastLine + 1;
|
||||
let belowLineEnd = model.getLineEnd(belowLine, true);
|
||||
|
||||
let insertAt = belowLineEnd - lastLineEnd + firstLineStart;
|
||||
let lineDelimiter = "";
|
||||
if (belowLine == this.getLineCount() - 1) {
|
||||
let delimiterStart = model.getLineEnd(lastLine);
|
||||
lineDelimiter = this.getText(delimiterStart, lastLineEnd);
|
||||
text = lineDelimiter + text.substr(0, text.length -
|
||||
lineDelimiter.length);
|
||||
}
|
||||
this.startCompoundChange();
|
||||
this.setText("", firstLineStart, lastLineEnd);
|
||||
this.setText(text, insertAt, insertAt);
|
||||
this.endCompoundChange();
|
||||
this.setSelection(insertAt + lineDelimiter.length,
|
||||
insertAt + text.length);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* The Orion Selection event handler. The current caret line is
|
||||
* highlighted and for Linux users the selected text is copied into the X11
|
||||
|
|
|
@ -192,6 +192,7 @@ SourceEditor.DEFAULTS = {
|
|||
* - action - name of the editor action to invoke.
|
||||
* - code - keyCode for the shortcut.
|
||||
* - accel - boolean for the Accel key (Cmd on Macs, Ctrl on Linux/Windows).
|
||||
* - ctrl - boolean for the Control key
|
||||
* - shift - boolean for the Shift key.
|
||||
* - alt - boolean for the Alt key.
|
||||
* - callback - optional function to invoke, if the action is not predefined
|
||||
|
|
|
@ -58,6 +58,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_bug725388_mouse_events.js \
|
||||
browser_bug707987_debugger_breakpoints.js \
|
||||
browser_bug712982_line_ruler_click.js \
|
||||
browser_bug725618_moveLines_shortcut.js \
|
||||
browser_bug700893_dirty_state.js \
|
||||
head.js \
|
||||
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/source-editor.jsm", tempScope);
|
||||
let SourceEditor = tempScope.SourceEditor;
|
||||
|
||||
let editor;
|
||||
let testWin;
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
const windowUrl = "data:application/vnd.mozilla.xul+xml,<?xml version='1.0'?>" +
|
||||
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
|
||||
" title='test for bug 725618 - moveLines shortcut' width='300' height='500'>" +
|
||||
"<box flex='1'/></window>";
|
||||
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
|
||||
testWin.addEventListener("load", function onWindowLoad() {
|
||||
testWin.removeEventListener("load", onWindowLoad, false);
|
||||
waitForFocus(initEditor, testWin);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function initEditor()
|
||||
{
|
||||
let box = testWin.document.querySelector("box");
|
||||
|
||||
let text = "target\nfoo\nbar"
|
||||
let config = {
|
||||
initialText: text,
|
||||
};
|
||||
|
||||
editor = new SourceEditor();
|
||||
editor.init(box, config, editorLoaded);
|
||||
}
|
||||
|
||||
function editorLoaded()
|
||||
{
|
||||
editor.focus();
|
||||
|
||||
editor.setCaretOffset(0);
|
||||
|
||||
let modifiers = {altKey: true, ctrlKey: Services.appinfo.OS == "Darwin"};
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "foo\ntarget\nbar", "Move lines down works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "foo\nbar\ntarget", "Move lines down works");
|
||||
is(editor.getSelectedText(), "target", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "foo\nbar\ntarget", "Check for bottom of editor works");
|
||||
is(editor.getSelectedText(), "target", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "foo\ntarget\nbar", "Move lines up works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar", "Move lines up works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar", "Check for top of editor works");
|
||||
is(editor.getSelectedText(), "target\n", "selection is correct");
|
||||
|
||||
editor.setSelection(0, 10);
|
||||
info("text within selection =" + editor.getSelectedText());
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "bar\ntarget\nfoo", "Multiple line move down works");
|
||||
is(editor.getSelectedText(), "target\nfoo", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "bar\ntarget\nfoo",
|
||||
"Check for bottom of editor works with multiple line selection");
|
||||
is(editor.getSelectedText(), "target\nfoo", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar", "Multiple line move up works");
|
||||
is(editor.getSelectedText(), "target\nfoo\n", "selection is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar",
|
||||
"Check for top of editor works with multiple line selection");
|
||||
is(editor.getSelectedText(), "target\nfoo\n", "selection is correct");
|
||||
|
||||
editor.readOnly = true;
|
||||
|
||||
editor.setCaretOffset(0);
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar",
|
||||
"Check for readOnly mode works with move lines up");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", modifiers, testWin);
|
||||
is(editor.getText(), "target\nfoo\nbar",
|
||||
"Check for readOnly mode works with move lines down");
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function()
|
||||
{
|
||||
editor.destroy();
|
||||
testWin.close();
|
||||
testWin = editor = null;
|
||||
});
|
|
@ -1198,11 +1198,19 @@ function CssRule(aCssSheet, aDomRule, aElement)
|
|||
this._cssSheet = aCssSheet;
|
||||
this._domRule = aDomRule;
|
||||
|
||||
let parentRule = aDomRule.parentRule;
|
||||
if (parentRule && parentRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE) {
|
||||
this.mediaText = parentRule.media.mediaText;
|
||||
}
|
||||
|
||||
if (this._cssSheet) {
|
||||
// parse _domRule.selectorText on call to this.selectors
|
||||
this._selectors = null;
|
||||
this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule);
|
||||
this.source = this._cssSheet.shortSource + ":" + this.line;
|
||||
if (this.mediaText) {
|
||||
this.source += " @media " + this.mediaText;
|
||||
}
|
||||
this.href = this._cssSheet.href;
|
||||
this.contentRule = this._cssSheet.contentSheet;
|
||||
} else if (aElement) {
|
||||
|
@ -1218,6 +1226,13 @@ function CssRule(aCssSheet, aDomRule, aElement)
|
|||
CssRule.prototype = {
|
||||
_passId: null,
|
||||
|
||||
mediaText: "",
|
||||
|
||||
get isMediaRule()
|
||||
{
|
||||
return !!this.mediaText;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the parent stylesheet is allowed by the CssLogic.sourceFilter.
|
||||
*
|
||||
|
|
|
@ -356,10 +356,20 @@ function Rule(aElementStyle, aOptions)
|
|||
this.style = aOptions.style || this.domRule.style;
|
||||
this.selectorText = aOptions.selectorText || this.domRule.selectorText;
|
||||
this.inherited = aOptions.inherited || null;
|
||||
|
||||
if (this.domRule) {
|
||||
let parentRule = this.domRule.parentRule;
|
||||
if (parentRule && parentRule.type == Ci.nsIDOMCSSRule.MEDIA_RULE) {
|
||||
this.mediaText = parentRule.media.mediaText;
|
||||
}
|
||||
}
|
||||
|
||||
this._getTextProperties();
|
||||
}
|
||||
|
||||
Rule.prototype = {
|
||||
mediaText: "",
|
||||
|
||||
get title()
|
||||
{
|
||||
if (this._title) {
|
||||
|
@ -380,7 +390,7 @@ Rule.prototype = {
|
|||
args, args.length);
|
||||
}
|
||||
|
||||
return this._title;
|
||||
return this._title + (this.mediaText ? " @media " + this.mediaText : "");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -722,8 +732,26 @@ CssRuleView.prototype = {
|
|||
}.bind(this);
|
||||
|
||||
this._createEditors();
|
||||
|
||||
// When creating a new property, we fake the normal property
|
||||
// editor behavior (focusing a property's value after entering its
|
||||
// name) by responding to the name's blur event, creating the
|
||||
// value editor, and grabbing focus to the value editor. But if
|
||||
// focus has already moved to another document, we won't be able
|
||||
// to move focus to the new editor.
|
||||
// Create a focusable item at the end of the editors to catch these
|
||||
// cases.
|
||||
this._focusBackstop = createChild(this.element, "div", {
|
||||
tabindex: 0,
|
||||
});
|
||||
this._backstopHandler = function() {
|
||||
// If this item is actually focused long enough to get the focus
|
||||
// event, allow focus to move on out of this document.
|
||||
moveFocus(this.doc.defaultView, FOCUS_FORWARD);
|
||||
}.bind(this);
|
||||
this._focusBackstop.addEventListener("focus", this._backstopHandler, false);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Update the rules for the currently highlighted element.
|
||||
*/
|
||||
|
@ -752,6 +780,12 @@ CssRuleView.prototype = {
|
|||
this._clearRules();
|
||||
this._viewedElement = null;
|
||||
this._elementStyle = null;
|
||||
|
||||
if (this._focusBackstop) {
|
||||
this._focusBackstop.removeEventListener("focus", this._backstopHandler, false);
|
||||
this._backstopHandler = null;
|
||||
this._focusBackstop = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -835,7 +869,6 @@ RuleEditor.prototype = {
|
|||
|
||||
this.openBrace = createChild(header, "span", {
|
||||
class: "ruleview-ruleopen",
|
||||
tabindex: "0",
|
||||
textContent: " {"
|
||||
});
|
||||
|
||||
|
|
|
@ -60,7 +60,10 @@ _BROWSER_TEST_FILES = \
|
|||
browser_ruleview_manipulation.js \
|
||||
browser_ruleview_override.js \
|
||||
browser_ruleview_ui.js \
|
||||
browser_ruleview_focus.js \
|
||||
browser_bug705707_is_content_stylesheet.js \
|
||||
browser_bug722196_property_view_media_queries.js \
|
||||
browser_bug722196_rule_view_media_queries.js \
|
||||
browser_bug_592743_specificity.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
@ -74,6 +77,7 @@ _BROWSER_TEST_PAGES = \
|
|||
browser_bug705707_is_content_stylesheet_script.css \
|
||||
browser_bug705707_is_content_stylesheet.xul \
|
||||
browser_bug705707_is_content_stylesheet_xul.css \
|
||||
browser_bug722196_identify_media_queries.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>test</title>
|
||||
<script type="application/javascript;version=1.7">
|
||||
|
||||
</script>
|
||||
<style>
|
||||
div {
|
||||
width: 1000px;
|
||||
height: 100px;
|
||||
background-color: #f00;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1px) {
|
||||
div {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,68 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that we correctly display appropriate media query titles in the
|
||||
// property view.
|
||||
|
||||
let doc;
|
||||
let stylePanel;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||
"test/browser_bug722196_identify_media_queries.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", docLoaded, true);
|
||||
}
|
||||
|
||||
function docLoaded()
|
||||
{
|
||||
browser.removeEventListener("load", docLoaded, true);
|
||||
doc = content.document;
|
||||
stylePanel = new StyleInspector(window);
|
||||
Services.obs.addObserver(checkSheets, "StyleInspector-opened", false);
|
||||
stylePanel.createPanel(false, function() {
|
||||
stylePanel.open(doc.body);
|
||||
});
|
||||
}
|
||||
|
||||
function checkSheets()
|
||||
{
|
||||
Services.obs.removeObserver(checkSheets, "StyleInspector-opened", false);
|
||||
|
||||
ok(stylePanel.isOpen(), "style inspector is open");
|
||||
|
||||
var div = doc.querySelector("div");
|
||||
ok(div, "captain, we have the div");
|
||||
|
||||
stylePanel.selectNode(div);
|
||||
|
||||
let cssLogic = stylePanel.cssLogic;
|
||||
cssLogic.processMatchedSelectors();
|
||||
|
||||
let _strings = Services.strings
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties");
|
||||
|
||||
let inline = _strings.GetStringFromName("rule.sourceInline");
|
||||
|
||||
let source1 = inline + ":8";
|
||||
let source2 = inline + ":15 @media screen and (min-width: 1px)";
|
||||
is(cssLogic._matchedRules[0][0].source, source1,
|
||||
"rule.source gives correct output for rule 1");
|
||||
is(cssLogic._matchedRules[1][0].source, source2,
|
||||
"rule.source gives correct output for rule 2");
|
||||
|
||||
Services.obs.addObserver(finishUp, "StyleInspector-closed", false);
|
||||
stylePanel.close();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
Services.obs.removeObserver(finishUp, "StyleInspector-closed", false);
|
||||
doc = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that we correctly display appropriate media query titles in the
|
||||
// rule view.
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource:///modules/devtools/CssRuleView.jsm", tempScope);
|
||||
let _ElementStyle = tempScope._ElementStyle;
|
||||
let doc;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||
"test/browser_bug722196_identify_media_queries.html";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", docLoaded, true);
|
||||
}
|
||||
|
||||
function docLoaded()
|
||||
{
|
||||
browser.removeEventListener("load", docLoaded, true);
|
||||
doc = content.document;
|
||||
checkSheets();
|
||||
}
|
||||
|
||||
function checkSheets()
|
||||
{
|
||||
var div = doc.querySelector("div");
|
||||
ok(div, "captain, we have the div");
|
||||
|
||||
let elementStyle = new _ElementStyle(div);
|
||||
is(elementStyle.rules.length, 3, "Should have 3 rules.");
|
||||
|
||||
let _strings = Services.strings
|
||||
.createBundle("chrome://browser/locale/devtools/styleinspector.properties");
|
||||
|
||||
let inline = _strings.GetStringFromName("rule.sourceInline");
|
||||
|
||||
is(elementStyle.rules[0].title, inline, "check rule 0 title");
|
||||
is(elementStyle.rules[1].title, inline +
|
||||
":15 @media screen and (min-width: 1px)", "check rule 1 title");
|
||||
is(elementStyle.rules[2].title, inline + ":8", "check rule 2 title");
|
||||
finishUp();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
doc = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that focus doesn't leave the style editor when adding a property
|
||||
// (bug 719916)
|
||||
|
||||
let doc;
|
||||
let stylePanel;
|
||||
|
||||
function waitForRuleView(aCallback)
|
||||
{
|
||||
if (InspectorUI.ruleView) {
|
||||
aCallback();
|
||||
return;
|
||||
}
|
||||
|
||||
let ruleViewFrame = InspectorUI.getToolIframe(InspectorUI.ruleViewObject);
|
||||
ruleViewFrame.addEventListener("load", function(evt) {
|
||||
ruleViewFrame.removeEventListener(evt.type, arguments.callee, true);
|
||||
executeSoon(function() {
|
||||
aCallback();
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
||||
function waitForEditorFocus(aParent, aCallback)
|
||||
{
|
||||
aParent.addEventListener("focus", function onFocus(evt) {
|
||||
if (evt.target.inplaceEditor) {
|
||||
aParent.removeEventListener("focus", onFocus, true);
|
||||
let editor = evt.target.inplaceEditor;
|
||||
executeSoon(function() {
|
||||
aCallback(editor);
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
||||
function openRuleView()
|
||||
{
|
||||
Services.obs.addObserver(function onOpened() {
|
||||
Services.obs.removeObserver(onOpened,
|
||||
InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
|
||||
// Highlight a node.
|
||||
let node = content.document.getElementsByTagName("h1")[0];
|
||||
InspectorUI.inspectNode(node);
|
||||
InspectorUI.stopInspecting();
|
||||
|
||||
// Open the rule view sidebar.
|
||||
waitForRuleView(testFocus);
|
||||
|
||||
InspectorUI.showSidebar();
|
||||
InspectorUI.ruleButton.click();
|
||||
|
||||
testFocus();
|
||||
}, InspectorUI.INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.openInspectorUI();
|
||||
}
|
||||
|
||||
function testFocus()
|
||||
{
|
||||
let ruleViewFrame = InspectorUI.getToolIframe(InspectorUI.ruleViewObject);
|
||||
let brace = ruleViewFrame.contentDocument.querySelectorAll(".ruleview-ruleclose")[0];
|
||||
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||
aEditor.input.value = "color";
|
||||
waitForEditorFocus(brace.parentNode, function onEditingValue(aEditor) {
|
||||
// If we actually get this focus we're ok.
|
||||
ok(true, "We got focus.");
|
||||
aEditor.input.value = "green";
|
||||
|
||||
// If we've retained focus, pressing return will start a new editor.
|
||||
// If not, we'll wait here until we time out.
|
||||
waitForEditorFocus(brace.parentNode, function onNewEditor(aEditor) {
|
||||
aEditor.input.blur();
|
||||
finishTest();
|
||||
});
|
||||
EventUtils.sendKey("return");
|
||||
});
|
||||
EventUtils.sendKey("return");
|
||||
});
|
||||
|
||||
brace.focus();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
doc = stylePanel = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||
doc = content.document;
|
||||
doc.title = "Rule View Test";
|
||||
waitForFocus(openRuleView, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,<h1>Some header text</h1>";
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Joe Walker <jwalker@mozilla.com> (original author)
|
||||
* Mihai Sucan <mihai.sucan@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
|
||||
|
@ -160,8 +161,6 @@ gcli.addCommand({
|
|||
}
|
||||
});
|
||||
|
||||
let breakpoints = [];
|
||||
|
||||
/**
|
||||
* 'break' command
|
||||
*/
|
||||
|
@ -180,17 +179,25 @@ gcli.addCommand({
|
|||
description: gcli.lookup("breaklistDesc"),
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
if (breakpoints.length === 0) {
|
||||
let win = HUDService.currentContext();
|
||||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
if (!dbg) {
|
||||
return gcli.lookup("breakaddDebuggerStopped");
|
||||
}
|
||||
let breakpoints = dbg.breakpoints;
|
||||
|
||||
if (Object.keys(breakpoints).length === 0) {
|
||||
return gcli.lookup("breaklistNone");
|
||||
}
|
||||
|
||||
let reply = gcli.lookup("breaklistIntro");
|
||||
reply += "<ol>";
|
||||
breakpoints.forEach(function(breakpoint) {
|
||||
for each (let breakpoint in breakpoints) {
|
||||
let text = gcli.lookupFormat("breaklistLineEntry",
|
||||
[breakpoint.file, breakpoint.line]);
|
||||
[breakpoint.location.url,
|
||||
breakpoint.location.line]);
|
||||
reply += "<li>" + text + "</li>";
|
||||
});
|
||||
};
|
||||
reply += "</ol>";
|
||||
return reply;
|
||||
}
|
||||
|
@ -248,14 +255,11 @@ gcli.addCommand({
|
|||
}
|
||||
var promise = context.createPromise();
|
||||
let position = { url: args.file, line: args.line };
|
||||
dbg.activeThread.setBreakpoint(position, function(aResponse, aBpClient) {
|
||||
if (aResponse.error) {
|
||||
promise.resolve(gcli.lookupFormat("breakaddFailed",
|
||||
[ aResponse.error ]));
|
||||
dbg.addBreakpoint(position, function(aBreakpoint, aError) {
|
||||
if (aError) {
|
||||
promise.resolve(gcli.lookupFormat("breakaddFailed", [aError]));
|
||||
return;
|
||||
}
|
||||
args.client = aBpClient;
|
||||
breakpoints.push(args);
|
||||
promise.resolve(gcli.lookup("breakaddAdded"));
|
||||
});
|
||||
return promise;
|
||||
|
@ -275,19 +279,37 @@ gcli.addCommand({
|
|||
type: {
|
||||
name: "number",
|
||||
min: 0,
|
||||
max: function() { return breakpoints.length - 1; }
|
||||
max: function() {
|
||||
let win = HUDService.currentContext();
|
||||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
if (!dbg) {
|
||||
return gcli.lookup("breakaddDebuggerStopped");
|
||||
}
|
||||
return Object.keys(dbg.breakpoints).length - 1;
|
||||
},
|
||||
},
|
||||
description: gcli.lookup("breakdelBreakidDesc")
|
||||
}
|
||||
],
|
||||
returnType: "html",
|
||||
exec: function(args, context) {
|
||||
let breakpoint = breakpoints.splice(args.breakid, 1)[0];
|
||||
var promise = context.createPromise();
|
||||
let win = HUDService.currentContext();
|
||||
let dbg = win.DebuggerUI.getDebugger(win.gBrowser.selectedTab);
|
||||
if (!dbg) {
|
||||
return gcli.lookup("breakaddDebuggerStopped");
|
||||
}
|
||||
|
||||
let breakpoints = dbg.breakpoints;
|
||||
let id = Object.keys(dbg.breakpoints)[args.breakid];
|
||||
if (!id || !(id in breakpoints)) {
|
||||
return gcli.lookup("breakNotFound");
|
||||
}
|
||||
|
||||
let promise = context.createPromise();
|
||||
try {
|
||||
breakpoint.client.remove(function(aResponse) {
|
||||
promise.resolve(gcli.lookup("breakdelRemoved"));
|
||||
});
|
||||
dbg.removeBreakpoint(breakpoints[id], function() {
|
||||
promise.resolve(gcli.lookup("breakdelRemoved"));
|
||||
});
|
||||
} catch (ex) {
|
||||
// If the debugger has been closed already, don't scare the user.
|
||||
promise.resolve(gcli.lookup("breakdelRemoved"));
|
||||
|
|
|
@ -255,6 +255,10 @@ breakdelBreakidDesc=Index of breakpoint
|
|||
# command to explain that a breakpoint was removed.
|
||||
breakdelRemoved=Breakpoint removed
|
||||
|
||||
# LOCALIZATION NOTE (breakNotFound) Used in the output of the 'break del'
|
||||
# command to explain that the breakpoint was not found.
|
||||
breakNotFound=Breakpoint was not found
|
||||
|
||||
# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
|
||||
# 'console close' command. This string is designed to be shown in a menu
|
||||
# alongside the command name, which is why it should be as short as possible.
|
||||
|
|
|
@ -139,6 +139,7 @@ if [ "$ENABLE_TESTS" ]; then
|
|||
browser/components/shell/test/Makefile
|
||||
browser/components/feeds/test/Makefile
|
||||
browser/components/feeds/test/chrome/Makefile
|
||||
browser/components/migration/tests/Makefile
|
||||
browser/components/places/tests/Makefile
|
||||
browser/components/places/tests/chrome/Makefile
|
||||
browser/components/places/tests/browser/Makefile
|
||||
|
|
|
@ -121,8 +121,6 @@ let Storage = {
|
|||
// want any data from private browsing to show up.
|
||||
PinnedLinks.resetCache();
|
||||
BlockedLinks.resetCache();
|
||||
|
||||
Pages.update();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -187,11 +185,6 @@ let AllPages = {
|
|||
*/
|
||||
_pages: [],
|
||||
|
||||
/**
|
||||
* Tells whether we already added a preference observer.
|
||||
*/
|
||||
_observing: false,
|
||||
|
||||
/**
|
||||
* Cached value that tells whether the New Tab Page feature is enabled.
|
||||
*/
|
||||
|
@ -203,12 +196,7 @@ let AllPages = {
|
|||
*/
|
||||
register: function AllPages_register(aPage) {
|
||||
this._pages.push(aPage);
|
||||
|
||||
// Add the preference observer if we haven't already.
|
||||
if (!this._observing) {
|
||||
this._observing = true;
|
||||
Services.prefs.addObserver(PREF_NEWTAB_ENABLED, this, true);
|
||||
}
|
||||
this._addObserver();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -238,6 +226,14 @@ let AllPages = {
|
|||
Services.prefs.setBoolPref(PREF_NEWTAB_ENABLED, !!aEnabled);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the number of registered New Tab Pages (i.e. the number of open
|
||||
* about:newtab instances).
|
||||
*/
|
||||
get length() {
|
||||
return this._pages.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates all currently active pages but the given one.
|
||||
* @param aExceptPage The page to exclude from updating.
|
||||
|
@ -264,6 +260,15 @@ let AllPages = {
|
|||
}, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a preference observer and turns itself into a no-op after the first
|
||||
* invokation.
|
||||
*/
|
||||
_addObserver: function AllPages_addObserver() {
|
||||
Services.prefs.addObserver(PREF_NEWTAB_ENABLED, this, true);
|
||||
this._addObserver = function () {};
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
@ -512,6 +517,8 @@ let Links = {
|
|||
this._links = aLinks;
|
||||
executeCallbacks();
|
||||
}.bind(this));
|
||||
|
||||
this._addObserver();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -544,7 +551,32 @@ let Links = {
|
|||
*/
|
||||
resetCache: function Links_resetCache() {
|
||||
this._links = [];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Implements the nsIObserver interface to get notified about browser history
|
||||
* sanitization.
|
||||
*/
|
||||
observe: function Links_observe(aSubject, aTopic, aData) {
|
||||
// Make sure to update open about:newtab instances. If there are no opened
|
||||
// pages we can just wait for the next new tab to populate the cache again.
|
||||
if (AllPages.length && AllPages.enabled)
|
||||
this.populateCache(function () { AllPages.update() }, true);
|
||||
else
|
||||
this._links = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a sanitization observer and turns itself into a no-op after the first
|
||||
* invokation.
|
||||
*/
|
||||
_addObserver: function Links_addObserver() {
|
||||
Services.obs.addObserver(this, "browser:purge-session-history", true);
|
||||
this._addObserver = function () {};
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -86,21 +86,24 @@ body[dir="rtl"] #errorPageContainer {
|
|||
-moz-margin-start: 80px;
|
||||
}
|
||||
|
||||
#technicalContent > h2, #expertContent > h2 {
|
||||
background : url("chrome://browser/skin/section_expanded.png") left 0 no-repeat;
|
||||
.expander > button {
|
||||
-moz-padding-start: 20px;
|
||||
-moz-margin-start: -20px;
|
||||
background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
|
||||
border: none;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent > h2,
|
||||
body[dir="rtl"] #expertContent > h2 {
|
||||
background-position: right 0;
|
||||
body[dir="rtl"] .expander > button {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
#technicalContent[collapsed] > h2,
|
||||
#expertContent[collapsed] > h2{
|
||||
background-image: url("chrome://browser/skin/section_collapsed.png");
|
||||
.expander[collapsed] > button {
|
||||
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent[collapsed] > h2,
|
||||
body[dir="rtl"] #expertContent[collapsed] > h2 {
|
||||
background-image: url("chrome://browser/skin/section_collapsed-rtl.png");
|
||||
body[dir="rtl"] .expander[collapsed] > button {
|
||||
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
|
||||
}
|
||||
|
|
До Ширина: | Высота: | Размер: 791 B После Ширина: | Высота: | Размер: 791 B |
До Ширина: | Высота: | Размер: 776 B После Ширина: | Высота: | Размер: 776 B |
До Ширина: | Высота: | Размер: 767 B После Ширина: | Высота: | Размер: 767 B |
|
@ -146,6 +146,7 @@
|
|||
direction: ltr;
|
||||
padding: 0;
|
||||
-moz-padding-start: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(KUI-close.png) center center no-repeat;
|
||||
}
|
|
@ -5,14 +5,16 @@ browser.jar:
|
|||
* skin/classic/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
|
||||
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
|
||||
skin/classic/browser/aboutSessionRestore-window-icon.png
|
||||
skin/classic/browser/aboutCertError.css (aboutCertError.css)
|
||||
skin/classic/browser/aboutCertError.css
|
||||
skin/classic/browser/aboutCertError_sectionCollapsed.png
|
||||
skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
|
||||
skin/classic/browser/aboutCertError_sectionExpanded.png
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/browser/aboutSyncTabs.css
|
||||
#endif
|
||||
skin/classic/browser/actionicon-tab.png
|
||||
* skin/classic/browser/browser.css (browser.css)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/browser/fullscreen-video.css
|
||||
skin/classic/browser/Geolocation-16.png
|
||||
skin/classic/browser/Geolocation-64.png
|
||||
skin/classic/browser/Go-arrow.png
|
||||
|
@ -27,9 +29,6 @@ browser.jar:
|
|||
skin/classic/browser/Privacy-16.png
|
||||
skin/classic/browser/Privacy-48.png
|
||||
skin/classic/browser/searchbar.css (searchbar.css)
|
||||
skin/classic/browser/section_collapsed.png
|
||||
skin/classic/browser/section_collapsed-rtl.png
|
||||
skin/classic/browser/section_expanded.png
|
||||
skin/classic/browser/Secure.png
|
||||
skin/classic/browser/Security-broken.png
|
||||
skin/classic/browser/setDesktopBackground.css
|
||||
|
|
|
@ -86,21 +86,24 @@ body[dir="rtl"] #errorPageContainer {
|
|||
-moz-margin-start: 80px;
|
||||
}
|
||||
|
||||
#technicalContent > h2, #expertContent > h2 {
|
||||
background : url("chrome://browser/skin/section_expanded.png") left 0 no-repeat;
|
||||
.expander > button {
|
||||
-moz-padding-start: 20px;
|
||||
-moz-margin-start: -20px;
|
||||
background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
|
||||
border: none;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent > h2,
|
||||
body[dir="rtl"] #expertContent > h2 {
|
||||
background-position: right 0;
|
||||
body[dir="rtl"] .expander > button {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
#technicalContent[collapsed] > h2,
|
||||
#expertContent[collapsed] > h2{
|
||||
background-image: url("chrome://browser/skin/section_collapsed.png");
|
||||
.expander[collapsed] > button {
|
||||
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent[collapsed] > h2,
|
||||
body[dir="rtl"] #expertContent[collapsed] > h2 {
|
||||
background-image: url("chrome://browser/skin/section_collapsed-rtl.png");
|
||||
body[dir="rtl"] .expander[collapsed] > button {
|
||||
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
|
||||
}
|
||||
|
|
До Ширина: | Высота: | Размер: 791 B После Ширина: | Высота: | Размер: 791 B |
До Ширина: | Высота: | Размер: 776 B После Ширина: | Высота: | Размер: 776 B |
До Ширина: | Высота: | Размер: 767 B После Ширина: | Высота: | Размер: 767 B |
|
@ -148,6 +148,7 @@
|
|||
direction: ltr;
|
||||
padding: 0;
|
||||
-moz-padding-start: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(KUI-close.png) center center no-repeat;
|
||||
}
|
|
@ -4,14 +4,16 @@ browser.jar:
|
|||
* skin/classic/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
|
||||
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
|
||||
skin/classic/browser/aboutSessionRestore-window-icon.png
|
||||
skin/classic/browser/aboutCertError.css (aboutCertError.css)
|
||||
skin/classic/browser/aboutCertError.css
|
||||
skin/classic/browser/aboutCertError_sectionCollapsed.png
|
||||
skin/classic/browser/aboutCertError_sectionCollapsed-rtl.png
|
||||
skin/classic/browser/aboutCertError_sectionExpanded.png
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/browser/aboutSyncTabs.css
|
||||
#endif
|
||||
skin/classic/browser/actionicon-tab.png
|
||||
* skin/classic/browser/browser.css (browser.css)
|
||||
* skin/classic/browser/engineManager.css (engineManager.css)
|
||||
skin/classic/browser/fullscreen-video.css
|
||||
skin/classic/browser/Geolocation-16.png
|
||||
skin/classic/browser/Geolocation-64.png
|
||||
skin/classic/browser/home.png
|
||||
|
@ -36,9 +38,6 @@ browser.jar:
|
|||
skin/classic/browser/searchbar-dropmarker.png
|
||||
skin/classic/browser/searchbar.css
|
||||
skin/classic/browser/Search.png
|
||||
skin/classic/browser/section_collapsed.png
|
||||
skin/classic/browser/section_collapsed-rtl.png
|
||||
skin/classic/browser/section_expanded.png
|
||||
skin/classic/browser/Secure-Glyph-White.png
|
||||
skin/classic/browser/keyhole-circle.png
|
||||
skin/classic/browser/Toolbar.png
|
||||
|
|
|
@ -86,21 +86,24 @@ body[dir="rtl"] #errorPageContainer {
|
|||
-moz-margin-start: 80px;
|
||||
}
|
||||
|
||||
#technicalContent > h2, #expertContent > h2 {
|
||||
background : url("chrome://browser/skin/section_expanded.png") left center no-repeat;
|
||||
.expander > button {
|
||||
-moz-padding-start: 20px;
|
||||
-moz-margin-start: -20px;
|
||||
background: url("chrome://browser/skin/aboutCertError_sectionExpanded.png") left center no-repeat;
|
||||
border: none;
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent > h2,
|
||||
body[dir="rtl"] #expertContent > h2 {
|
||||
body[dir="rtl"] .expander > button {
|
||||
background-position: right center;
|
||||
}
|
||||
|
||||
#technicalContent[collapsed] > h2,
|
||||
#expertContent[collapsed] > h2{
|
||||
background-image: url("chrome://browser/skin/section_collapsed.png");
|
||||
.expander[collapsed] > button {
|
||||
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed.png");
|
||||
}
|
||||
|
||||
body[dir="rtl"] #technicalContent[collapsed] > h2,
|
||||
body[dir="rtl"] #expertContent[collapsed] > h2 {
|
||||
background-image: url("chrome://browser/skin/section_collapsed-rtl.png");
|
||||
body[dir="rtl"] .expander[collapsed] > button {
|
||||
background-image: url("chrome://browser/skin/aboutCertError_sectionCollapsed-rtl.png");
|
||||
}
|
||||
|
|
До Ширина: | Высота: | Размер: 791 B После Ширина: | Высота: | Размер: 791 B |
До Ширина: | Высота: | Размер: 776 B После Ширина: | Высота: | Размер: 776 B |
До Ширина: | Высота: | Размер: 767 B После Ширина: | Высота: | Размер: 767 B |
|
@ -146,6 +146,7 @@
|
|||
direction: ltr;
|
||||
padding: 0;
|
||||
-moz-padding-start: 20px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.bestmatch {
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
#close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: url(KUI-close.png) center center no-repeat;
|
||||
}
|