зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-i
This commit is contained in:
Коммит
a93cb7d802
|
@ -12,7 +12,7 @@
|
|||
#include "States.h"
|
||||
|
||||
#include "mozilla/EventStateManager.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
@ -127,7 +127,7 @@ AccShowEvent::
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccTextSelChangeEvent::AccTextSelChangeEvent(HyperTextAccessible* aTarget,
|
||||
Selection* aSelection,
|
||||
dom::Selection* aSelection,
|
||||
int32_t aReason) :
|
||||
AccEvent(nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED, aTarget,
|
||||
eAutoDetect, eCoalesceTextSelChange),
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class Selection;
|
||||
}
|
||||
|
||||
namespace a11y {
|
||||
|
||||
|
@ -367,7 +369,8 @@ private:
|
|||
class AccTextSelChangeEvent : public AccEvent
|
||||
{
|
||||
public:
|
||||
AccTextSelChangeEvent(HyperTextAccessible* aTarget, Selection* aSelection,
|
||||
AccTextSelChangeEvent(HyperTextAccessible* aTarget,
|
||||
dom::Selection* aSelection,
|
||||
int32_t aReason);
|
||||
virtual ~AccTextSelChangeEvent();
|
||||
|
||||
|
@ -386,7 +389,7 @@ public:
|
|||
bool IsCaretMoveOnly() const;
|
||||
|
||||
private:
|
||||
nsRefPtr<Selection> mSel;
|
||||
nsRefPtr<dom::Selection> mSel;
|
||||
int32_t mReason;
|
||||
|
||||
friend class EventQueue;
|
||||
|
|
|
@ -14,11 +14,12 @@
|
|||
#include "nsIAccessibleTypes.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
using mozilla::dom::Selection;
|
||||
|
||||
struct mozilla::a11y::SelData MOZ_FINAL
|
||||
{
|
||||
|
|
|
@ -42,7 +42,7 @@ HyperTextAccessible::IsValidRange(int32_t aStartOffset, int32_t aEndOffset)
|
|||
inline bool
|
||||
HyperTextAccessible::AddToSelection(int32_t aStartOffset, int32_t aEndOffset)
|
||||
{
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
return domSel &&
|
||||
SetSelectionBoundsAt(domSel->GetRangeCount(), aStartOffset, aEndOffset);
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ HyperTextAccessible::FrameSelection() const
|
|||
return frame ? frame->GetFrameSelection() : nullptr;
|
||||
}
|
||||
|
||||
inline Selection*
|
||||
inline dom::Selection*
|
||||
HyperTextAccessible::DOMSelection() const
|
||||
{
|
||||
nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "nsTextFragment.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/EventStates.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "gfxSkipChars.h"
|
||||
#include <algorithm>
|
||||
|
@ -1117,7 +1117,7 @@ HyperTextAccessible::SetSelectionRange(int32_t aStartPos, int32_t aEndPos)
|
|||
if (isFocusable)
|
||||
TakeFocus();
|
||||
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
NS_ENSURE_STATE(domSel);
|
||||
|
||||
// Set up the selection.
|
||||
|
@ -1164,7 +1164,7 @@ HyperTextAccessible::CaretOffset() const
|
|||
|
||||
// Turn the focus node and offset of the selection into caret hypretext
|
||||
// offset.
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
NS_ENSURE_TRUE(domSel, -1);
|
||||
|
||||
nsINode* focusNode = domSel->GetFocusNode();
|
||||
|
@ -1194,7 +1194,7 @@ HyperTextAccessible::CaretLineNumber()
|
|||
if (!frameSelection)
|
||||
return -1;
|
||||
|
||||
Selection* domSel =
|
||||
dom::Selection* domSel =
|
||||
frameSelection->GetSelection(nsISelectionController::SELECTION_NORMAL);
|
||||
if (!domSel)
|
||||
return - 1;
|
||||
|
@ -1310,7 +1310,7 @@ HyperTextAccessible::GetSelectionDOMRanges(int16_t aType,
|
|||
frameSelection->GetDisplaySelection() <= nsISelectionController::SELECTION_HIDDEN)
|
||||
return;
|
||||
|
||||
Selection* domSel = frameSelection->GetSelection(aType);
|
||||
dom::Selection* domSel = frameSelection->GetSelection(aType);
|
||||
if (!domSel)
|
||||
return;
|
||||
|
||||
|
@ -1397,7 +1397,7 @@ HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
|
|||
int32_t startOffset = ConvertMagicOffset(aStartOffset);
|
||||
int32_t endOffset = ConvertMagicOffset(aEndOffset);
|
||||
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
if (!domSel)
|
||||
return false;
|
||||
|
||||
|
@ -1426,7 +1426,7 @@ HyperTextAccessible::SetSelectionBoundsAt(int32_t aSelectionNum,
|
|||
bool
|
||||
HyperTextAccessible::RemoveFromSelection(int32_t aSelectionNum)
|
||||
{
|
||||
Selection* domSel = DOMSelection();
|
||||
dom::Selection* domSel = DOMSelection();
|
||||
if (!domSel)
|
||||
return false;
|
||||
|
||||
|
@ -1521,7 +1521,7 @@ HyperTextAccessible::SelectionRanges(nsTArray<a11y::TextRange>* aRanges) const
|
|||
{
|
||||
NS_ASSERTION(aRanges->Length() != 0, "TextRange array supposed to be empty");
|
||||
|
||||
Selection* sel = DOMSelection();
|
||||
dom::Selection* sel = DOMSelection();
|
||||
if (!sel)
|
||||
return;
|
||||
|
||||
|
@ -1848,7 +1848,7 @@ HyperTextAccessible::GetSpellTextAttribute(nsINode* aNode,
|
|||
if (!fs)
|
||||
return NS_OK;
|
||||
|
||||
Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
|
||||
dom::Selection* domSel = fs->GetSelection(nsISelectionController::SELECTION_SPELLCHECK);
|
||||
if (!domSel)
|
||||
return NS_OK;
|
||||
|
||||
|
|
|
@ -489,7 +489,7 @@ protected:
|
|||
* Return frame/DOM selection object for the accessible.
|
||||
*/
|
||||
already_AddRefed<nsFrameSelection> FrameSelection() const;
|
||||
Selection* DOMSelection() const;
|
||||
dom::Selection* DOMSelection() const;
|
||||
|
||||
/**
|
||||
* Return selection ranges within the accessible subtree.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[
|
||||
{"size": 169226356,
|
||||
"digest": "f9456848fd661b8be05d6a30607fad4787bcecfe676b53f9a4074653fdda6a377c961038c866c5d83355e3afd89f1a3bd947a142aeaf7dd7d81b6c376185badd",
|
||||
{"size": 156447892,
|
||||
"digest": "02b2e6bcaff4ccadfd85a75cc1dfb526be7937673ed18b2c6fb7fe2256a725bc778d513e3820d86adaec1636e1771bd0c5663e17bf2d3f1d6b445ff1e0a136f2",
|
||||
"filename": "backup-flame.tar.xz",
|
||||
"algorithm": "sha512"
|
||||
}
|
||||
|
|
|
@ -139,7 +139,6 @@
|
|||
@BINPATH@/components/composer.xpt
|
||||
@BINPATH@/components/content_base.xpt
|
||||
@BINPATH@/components/content_events.xpt
|
||||
@BINPATH@/components/content_canvas.xpt
|
||||
@BINPATH@/components/content_htmldoc.xpt
|
||||
@BINPATH@/components/content_html.xpt
|
||||
@BINPATH@/components/content_xslt.xpt
|
||||
|
|
|
@ -1228,7 +1228,7 @@ pref("devtools.toolbox.footer.height", 250);
|
|||
pref("devtools.toolbox.sidebar.width", 500);
|
||||
pref("devtools.toolbox.host", "bottom");
|
||||
pref("devtools.toolbox.selectedTool", "webconsole");
|
||||
pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","tilt toggle","scratchpad","resize toggle"]');
|
||||
pref("devtools.toolbox.toolbarSpec", '["splitconsole", "paintflashing toggle","tilt toggle","scratchpad","resize toggle","eyedropper"]');
|
||||
pref("devtools.toolbox.sideEnabled", true);
|
||||
pref("devtools.toolbox.zoomValue", "1");
|
||||
|
||||
|
@ -1239,6 +1239,7 @@ pref("devtools.command-button-paintflashing.enabled", false);
|
|||
pref("devtools.command-button-tilt.enabled", false);
|
||||
pref("devtools.command-button-scratchpad.enabled", false);
|
||||
pref("devtools.command-button-responsive.enabled", true);
|
||||
pref("devtools.command-button-eyedropper.enabled", false);
|
||||
|
||||
// Inspector preferences
|
||||
// Enable the Inspector
|
||||
|
|
|
@ -191,6 +191,60 @@ let AboutHomeListener = {
|
|||
};
|
||||
AboutHomeListener.init(this);
|
||||
|
||||
|
||||
let ContentSearchMediator = {
|
||||
|
||||
whitelist: new Set([
|
||||
"about:newtab",
|
||||
]),
|
||||
|
||||
init: function (chromeGlobal) {
|
||||
chromeGlobal.addEventListener("ContentSearchClient", this, true, true);
|
||||
addMessageListener("ContentSearch", this);
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
if (this._contentWhitelisted) {
|
||||
this._sendMsg(event.detail.type, event.detail.data);
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function (msg) {
|
||||
if (msg.data.type == "AddToWhitelist") {
|
||||
for (let uri of msg.data.data) {
|
||||
this.whitelist.add(uri);
|
||||
}
|
||||
this._sendMsg("AddToWhitelistAck");
|
||||
return;
|
||||
}
|
||||
if (this._contentWhitelisted) {
|
||||
this._fireEvent(msg.data.type, msg.data.data);
|
||||
}
|
||||
},
|
||||
|
||||
get _contentWhitelisted() {
|
||||
return this.whitelist.has(content.document.documentURI.toLowerCase());
|
||||
},
|
||||
|
||||
_sendMsg: function (type, data=null) {
|
||||
sendAsyncMessage("ContentSearch", {
|
||||
type: type,
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
_fireEvent: function (type, data=null) {
|
||||
content.dispatchEvent(new content.CustomEvent("ContentSearchService", {
|
||||
detail: {
|
||||
type: type,
|
||||
data: data,
|
||||
},
|
||||
}));
|
||||
},
|
||||
};
|
||||
ContentSearchMediator.init(this);
|
||||
|
||||
|
||||
var global = this;
|
||||
|
||||
// Lazily load the finder code
|
||||
|
|
|
@ -197,12 +197,18 @@ let gGrid = {
|
|||
}
|
||||
|
||||
let availSpace = document.documentElement.clientHeight - this._cellMargin -
|
||||
document.querySelector("#newtab-margin-undo-container").offsetHeight;
|
||||
document.querySelector("#newtab-margin-undo-container").offsetHeight -
|
||||
document.querySelector("#newtab-search-form").offsetHeight;
|
||||
let visibleRows = Math.floor(availSpace / this._cellHeight);
|
||||
this._node.style.height = this._computeHeight() + "px";
|
||||
this._node.style.maxHeight = this._computeHeight(visibleRows) + "px";
|
||||
this._node.style.maxWidth = gGridPrefs.gridColumns * this._cellWidth +
|
||||
GRID_WIDTH_EXTRA + "px";
|
||||
|
||||
// Resize the search bar.
|
||||
let width = parseFloat(window.getComputedStyle(this._node).width);
|
||||
let visibleCols = Math.floor(width / this._cellWidth);
|
||||
gSearch.setWidth(visibleCols * this._cellWidth - this._cellMargin);
|
||||
},
|
||||
|
||||
_shouldRenderGrid : function Grid_shouldRenderGrid() {
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
* 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/. */
|
||||
|
||||
input {
|
||||
font: message-box !important;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
|
||||
input[type=button] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -12,6 +17,7 @@ input[type=button] {
|
|||
position: relative;
|
||||
-moz-box-flex: 1;
|
||||
-moz-user-focus: normal;
|
||||
-moz-box-orient: vertical;
|
||||
}
|
||||
|
||||
#newtab-scrollbox:not([page-disabled]) {
|
||||
|
@ -54,6 +60,7 @@ input[type=button] {
|
|||
#newtab-margin-undo-container {
|
||||
display: -moz-box;
|
||||
-moz-box-pack: center;
|
||||
margin-bottom: 26px; /* 32 - 6 search form top "padding" */
|
||||
}
|
||||
|
||||
#newtab-horizontal-margin {
|
||||
|
@ -64,10 +71,17 @@ input[type=button] {
|
|||
#newtab-margin-top,
|
||||
#newtab-margin-bottom {
|
||||
display: -moz-box;
|
||||
-moz-box-flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#newtab-margin-top {
|
||||
-moz-box-flex: 1;
|
||||
}
|
||||
|
||||
#newtab-margin-bottom {
|
||||
-moz-box-flex: 2;
|
||||
}
|
||||
|
||||
.newtab-side-margin {
|
||||
min-width: 16px;
|
||||
-moz-box-flex: 1;
|
||||
|
@ -213,7 +227,7 @@ input[type=button] {
|
|||
opacity: 0.01;
|
||||
}
|
||||
|
||||
/* PANEL */
|
||||
/* SPONSORED PANEL */
|
||||
#sponsored-panel {
|
||||
width: 330px;
|
||||
}
|
||||
|
@ -225,3 +239,156 @@ input[type=button] {
|
|||
#sponsored-panel .text-link {
|
||||
margin: 12px 0 0;
|
||||
}
|
||||
|
||||
/* SEARCH */
|
||||
#newtab-search-container {
|
||||
display: -moz-box;
|
||||
position: relative;
|
||||
-moz-box-align: center;
|
||||
-moz-box-pack: center;
|
||||
}
|
||||
|
||||
#newtab-search-container[page-disabled] {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#newtab-search-form {
|
||||
display: -moz-box;
|
||||
-moz-box-orient: horizontal;
|
||||
-moz-box-align: center;
|
||||
height: 44px; /* 32 + 6 logo top "padding" + 6 logo bottom "padding" */
|
||||
margin-bottom: 10px; /* 32 - 16 tiles top margin - 6 logo bottom "padding" */
|
||||
}
|
||||
|
||||
#newtab-search-logo {
|
||||
display: -moz-box;
|
||||
width: 77px; /* 65 image width + 6 left "padding" + 6 right "padding" */
|
||||
height: 38px; /* 26 image height + 6 top "padding" + 6 bottom "padding" */
|
||||
border: 1px solid transparent;
|
||||
-moz-margin-end: 8px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 65px 26px;
|
||||
}
|
||||
|
||||
#newtab-search-logo[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#newtab-search-logo[active],
|
||||
#newtab-search-logo:hover {
|
||||
background-color: #e9e9e9;
|
||||
border: 1px solid rgb(226, 227, 229);
|
||||
border-radius: 2.5px;
|
||||
}
|
||||
|
||||
#newtab-search-text {
|
||||
height: 32px;
|
||||
-moz-box-flex: 1;
|
||||
|
||||
padding: 0 8px;
|
||||
background: hsla(0,0%,100%,.9) padding-box;
|
||||
border: 1px solid;
|
||||
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
|
||||
box-shadow: 0 1px 0 hsla(210,65%,9%,.02) inset,
|
||||
0 0 2px hsla(210,65%,9%,.1) inset,
|
||||
0 1px 0 hsla(0,0%,100%,.2);
|
||||
border-radius: 2.5px 0 0 2.5px;
|
||||
}
|
||||
|
||||
#newtab-search-text:-moz-dir(rtl) {
|
||||
border-radius: 0 2.5px 2.5px 0;
|
||||
}
|
||||
|
||||
#newtab-search-text:focus,
|
||||
#newtab-search-text[autofocus] {
|
||||
border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6);
|
||||
}
|
||||
|
||||
#newtab-search-submit {
|
||||
height: 32px;
|
||||
|
||||
-moz-margin-start: -1px;
|
||||
background: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box;
|
||||
padding: 0 9px;
|
||||
border: 1px solid;
|
||||
border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2);
|
||||
-moz-border-start: 1px solid transparent;
|
||||
border-radius: 0 2.5px 2.5px 0;
|
||||
box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset,
|
||||
0 1px 0 hsla(0,0%,100%,.2);
|
||||
cursor: pointer;
|
||||
transition-property: background-color, border-color, box-shadow;
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
#newtab-search-submit:-moz-dir(rtl) {
|
||||
border-radius: 2.5px 0 0 2.5px;
|
||||
}
|
||||
|
||||
#newtab-search-text:focus + #newtab-search-submit,
|
||||
#newtab-search-text + #newtab-search-submit:hover,
|
||||
#newtab-search-text[autofocus] + #newtab-search-submit {
|
||||
border-color: #59b5fc #45a3e7 #3294d5;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#newtab-search-text:focus + #newtab-search-submit,
|
||||
#newtab-search-text[autofocus] + #newtab-search-submit {
|
||||
background-image: linear-gradient(#4cb1ff, #1793e5);
|
||||
box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
|
||||
0 0 0 1px hsla(0,0%,100%,.1) inset,
|
||||
0 1px 0 hsla(210,54%,20%,.03);
|
||||
}
|
||||
|
||||
#newtab-search-text + #newtab-search-submit:hover {
|
||||
background-image: linear-gradient(#66bdff, #0d9eff);
|
||||
box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset,
|
||||
0 0 0 1px hsla(0,0%,100%,.1) inset,
|
||||
0 1px 0 hsla(210,54%,20%,.03),
|
||||
0 0 4px hsla(206,100%,20%,.2);
|
||||
}
|
||||
|
||||
#newtab-search-text + #newtab-search-submit:hover:active {
|
||||
box-shadow: 0 1px 1px hsla(211,79%,6%,.1) inset,
|
||||
0 0 1px hsla(211,79%,6%,.2) inset;
|
||||
transition-duration: 0ms;
|
||||
}
|
||||
|
||||
#newtab-search-panel .panel-arrowcontent {
|
||||
-moz-padding-start: 0;
|
||||
-moz-padding-end: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
background: rgb(248, 250, 251);
|
||||
}
|
||||
|
||||
.newtab-search-panel-engine {
|
||||
-moz-box-align: center;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
-moz-padding-start: 24px;
|
||||
-moz-padding-end: 24px;
|
||||
}
|
||||
|
||||
.newtab-search-panel-engine:not(:last-child) {
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.newtab-search-panel-engine > image {
|
||||
-moz-margin-end: 8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.newtab-search-panel-engine > label {
|
||||
-moz-padding-start: 0;
|
||||
-moz-margin-start: 0;
|
||||
color: rgb(130, 132, 133);
|
||||
}
|
||||
|
||||
.newtab-search-panel-engine[selected] {
|
||||
background: url("chrome://global/skin/menu/shared-menu-check.png") center left 4px no-repeat transparent;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ function inPrivateBrowsingMode() {
|
|||
}
|
||||
|
||||
const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
||||
const XUL_NAMESPACE = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
#include transformations.js
|
||||
#include page.js
|
||||
|
@ -54,6 +55,7 @@ const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|||
#include dropPreview.js
|
||||
#include updater.js
|
||||
#include undo.js
|
||||
#include search.js
|
||||
|
||||
// Everything is loaded. Initialize the New Tab Page.
|
||||
gPage.init();
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
<!DOCTYPE window [
|
||||
<!ENTITY % newTabDTD SYSTEM "chrome://browser/locale/newTab.dtd">
|
||||
%newTabDTD;
|
||||
<!ENTITY % searchBarDTD SYSTEM "chrome://browser/locale/searchbar.dtd">
|
||||
%searchBarDTD;
|
||||
]>
|
||||
|
||||
<xul:window id="newtab-window" xmlns="http://www.w3.org/1999/xhtml"
|
||||
|
@ -24,6 +26,13 @@
|
|||
value="&newtab.panel.link.text;" />
|
||||
</xul:panel>
|
||||
|
||||
<xul:panel id="newtab-search-panel" orient="vertical" type="arrow"
|
||||
noautohide="true">
|
||||
<xul:hbox id="newtab-search-manage" class="newtab-search-panel-engine">
|
||||
<xul:label>&cmd_engineManager.label;</xul:label>
|
||||
</xul:hbox>
|
||||
</xul:panel>
|
||||
|
||||
<div id="newtab-scrollbox">
|
||||
|
||||
<div id="newtab-vertical-margin">
|
||||
|
@ -46,6 +55,16 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="newtab-search-container">
|
||||
<form id="newtab-search-form" name="searchForm">
|
||||
<div id="newtab-search-logo"/>
|
||||
<input type="text" name="q" value="" id="newtab-search-text"
|
||||
maxlength="256" dir="auto"/>
|
||||
<input id="newtab-search-submit" type="submit"
|
||||
value="&searchEndCap.label;"/>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="newtab-horizontal-margin">
|
||||
<div class="newtab-side-margin"/>
|
||||
|
||||
|
|
|
@ -111,6 +111,8 @@ let gPage = {
|
|||
|
||||
this._initialized = true;
|
||||
|
||||
gSearch.init();
|
||||
|
||||
this._mutationObserver = new MutationObserver(() => {
|
||||
if (this.allowBackgroundCaptures) {
|
||||
Services.telemetry.getHistogramById("NEWTAB_PAGE_SHOWN").add(true);
|
||||
|
@ -138,6 +140,10 @@ let gPage = {
|
|||
let shownCount = Math.min(10, count);
|
||||
Services.telemetry.getHistogramById(shownId).add(shownCount);
|
||||
}
|
||||
|
||||
// content.js isn't loaded for the page while it's in the preloader,
|
||||
// which is why this is necessary.
|
||||
gSearch.setUpInitialState();
|
||||
}
|
||||
});
|
||||
this._mutationObserver.observe(document.documentElement, {
|
||||
|
@ -164,7 +170,7 @@ let gPage = {
|
|||
*/
|
||||
_updateAttributes: function Page_updateAttributes(aValue) {
|
||||
// Set the nodes' states.
|
||||
let nodeSelector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid";
|
||||
let nodeSelector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid, #newtab-search-container";
|
||||
for (let node of document.querySelectorAll(nodeSelector)) {
|
||||
if (aValue)
|
||||
node.removeAttribute("page-disabled");
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
#ifdef 0
|
||||
/* 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/. */
|
||||
#endif
|
||||
|
||||
let gSearch = {
|
||||
|
||||
currentEngineName: null,
|
||||
|
||||
init: function () {
|
||||
for (let idSuffix of this._nodeIDSuffixes) {
|
||||
this._nodes[idSuffix] =
|
||||
document.getElementById("newtab-search-" + idSuffix);
|
||||
}
|
||||
|
||||
window.addEventListener("ContentSearchService", this);
|
||||
this.setUpInitialState();
|
||||
},
|
||||
|
||||
setUpInitialState: function () {
|
||||
this._send("GetState");
|
||||
},
|
||||
|
||||
showPanel: function () {
|
||||
let panel = this._nodes.panel;
|
||||
let logo = this._nodes.logo;
|
||||
panel.openPopup(logo);
|
||||
logo.setAttribute("active", "true");
|
||||
panel.addEventListener("popuphidden", function onHidden() {
|
||||
panel.removeEventListener("popuphidden", onHidden);
|
||||
logo.removeAttribute("active");
|
||||
});
|
||||
},
|
||||
|
||||
search: function (event) {
|
||||
event.preventDefault();
|
||||
let searchStr = this._nodes.text.value;
|
||||
if (this.currentEngineName && searchStr.length) {
|
||||
this._send("Search", {
|
||||
engineName: this.currentEngineName,
|
||||
searchString: searchStr,
|
||||
whence: "newtab",
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
manageEngines: function () {
|
||||
this._nodes.panel.hidePopup();
|
||||
this._send("ManageEngines");
|
||||
},
|
||||
|
||||
setWidth: function (width) {
|
||||
this._nodes.form.style.width = width + "px";
|
||||
this._nodes.form.style.maxWidth = width + "px";
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
this["on" + event.detail.type](event.detail.data);
|
||||
},
|
||||
|
||||
onState: function (data) {
|
||||
this._makePanel(data.engines);
|
||||
this._setCurrentEngine(data.currentEngine);
|
||||
this._initWhenInitalStateReceived();
|
||||
},
|
||||
|
||||
onCurrentEngine: function (engineName) {
|
||||
this._setCurrentEngine(engineName);
|
||||
},
|
||||
|
||||
_nodeIDSuffixes: [
|
||||
"form",
|
||||
"logo",
|
||||
"manage",
|
||||
"panel",
|
||||
"text",
|
||||
],
|
||||
|
||||
_nodes: {},
|
||||
|
||||
_initWhenInitalStateReceived: function () {
|
||||
this._nodes.form.addEventListener("submit", e => this.search(e));
|
||||
this._nodes.logo.addEventListener("click", e => this.showPanel());
|
||||
this._nodes.manage.addEventListener("click", e => this.manageEngines());
|
||||
this._initWhenInitalStateReceived = function () {};
|
||||
},
|
||||
|
||||
_send: function (type, data=null) {
|
||||
window.dispatchEvent(new CustomEvent("ContentSearchClient", {
|
||||
detail: {
|
||||
type: type,
|
||||
data: data,
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
_makePanel: function (engines) {
|
||||
let panel = this._nodes.panel;
|
||||
|
||||
// Empty the panel except for the Manage Engines row.
|
||||
let i = 0;
|
||||
while (i < panel.childNodes.length) {
|
||||
let node = panel.childNodes[i];
|
||||
if (node != this._nodes.manage) {
|
||||
panel.removeChild(node);
|
||||
}
|
||||
else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Add all the engines.
|
||||
for (let engine of engines) {
|
||||
panel.insertBefore(this._makePanelEngine(panel, engine),
|
||||
this._nodes.manage);
|
||||
}
|
||||
},
|
||||
|
||||
_makePanelEngine: function (panel, engine) {
|
||||
let box = document.createElementNS(XUL_NAMESPACE, "hbox");
|
||||
box.className = "newtab-search-panel-engine";
|
||||
box.setAttribute("engine", engine.name);
|
||||
|
||||
box.addEventListener("click", () => {
|
||||
this._send("SetCurrentEngine", engine.name);
|
||||
panel.hidePopup();
|
||||
this._nodes.text.focus();
|
||||
});
|
||||
|
||||
let image = document.createElementNS(XUL_NAMESPACE, "image");
|
||||
if (engine.iconURI) {
|
||||
image.setAttribute("src", engine.iconURI);
|
||||
}
|
||||
box.appendChild(image);
|
||||
|
||||
let label = document.createElementNS(XUL_NAMESPACE, "label");
|
||||
label.setAttribute("value", engine.name);
|
||||
box.appendChild(label);
|
||||
|
||||
return box;
|
||||
},
|
||||
|
||||
_setCurrentEngine: function (engine) {
|
||||
this.currentEngineName = engine.name;
|
||||
|
||||
// Set the logo.
|
||||
let logoURI = window.devicePixelRatio == 2 ? engine.logo2xURI :
|
||||
engine.logoURI;
|
||||
if (logoURI) {
|
||||
this._nodes.logo.hidden = false;
|
||||
this._nodes.logo.style.backgroundImage = "url(" + logoURI + ")";
|
||||
this._nodes.text.placeholder = "";
|
||||
}
|
||||
else {
|
||||
this._nodes.logo.hidden = true;
|
||||
this._nodes.text.placeholder = engine.name;
|
||||
}
|
||||
|
||||
// Set the selected state of all the engines in the panel.
|
||||
for (let box of this._nodes.panel.childNodes) {
|
||||
if (box.getAttribute("engine") == engine.name) {
|
||||
box.setAttribute("selected", "true");
|
||||
}
|
||||
else {
|
||||
box.removeAttribute("selected");
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
|
@ -399,7 +399,6 @@ skip-if = e10s # Bug ????? - test calls gBrowser.contentWindow.stop
|
|||
[browser_urlbar_search_healthreport.js]
|
||||
skip-if = e10s # Bug ?????? - FHR tests failing (either with "no data for today" or "2 records for today")
|
||||
[browser_utilityOverlay.js]
|
||||
skip-if = e10s # Bug 921947 - openNewTabWith failed with window.content.document being null
|
||||
[browser_visibleFindSelection.js]
|
||||
skip-if = e10s # Bug ?????? - test directly manipulates content
|
||||
[browser_visibleLabel.js]
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
[DEFAULT]
|
||||
support-files = head.js
|
||||
skip-if = e10s # Bug ?????? - about:newtab tests don't work in e10s
|
||||
support-files =
|
||||
head.js
|
||||
searchEngineLogo.xml
|
||||
searchEngineNoLogo.xml
|
||||
|
||||
[browser_newtab_background_captures.js]
|
||||
[browser_newtab_block.js]
|
||||
|
@ -25,6 +28,7 @@ skip-if = os == "mac" # Intermittent failures, bug 898317
|
|||
[browser_newtab_focus.js]
|
||||
[browser_newtab_perwindow_private_browsing.js]
|
||||
[browser_newtab_reset.js]
|
||||
[browser_newtab_search.js]
|
||||
[browser_newtab_sponsored_icon_click.js]
|
||||
[browser_newtab_tabsync.js]
|
||||
[browser_newtab_undo.js]
|
||||
|
|
|
@ -9,9 +9,9 @@ function runTests() {
|
|||
Services.prefs.setIntPref("accessibility.tabfocus", 7);
|
||||
|
||||
// Focus count in new tab page.
|
||||
// 28 = 9 * 3 + 1 = 9 sites and 1 toggle button, each site has a link, a pin
|
||||
// and a remove button.
|
||||
let FOCUS_COUNT = 28;
|
||||
// 30 = 9 * 3 + 3 = 9 sites, each with link, pin and remove buttons; search
|
||||
// bar; search button; and toggle button.
|
||||
let FOCUS_COUNT = 30;
|
||||
|
||||
// Create a new tab page.
|
||||
yield setLinks("0,1,2,3,4,5,6,7,8");
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// See browser/components/search/test/browser_*_behavior.js for tests of actual
|
||||
// searches.
|
||||
|
||||
const ENGINE_LOGO = "searchEngineLogo.xml";
|
||||
const ENGINE_NO_LOGO = "searchEngineNoLogo.xml";
|
||||
|
||||
const SERVICE_EVENT_NAME = "ContentSearchService";
|
||||
|
||||
const LOGO_LOW_DPI_SIZE = [65, 26];
|
||||
const LOGO_HIGH_DPI_SIZE = [130, 52];
|
||||
|
||||
// The test has an expected search event queue and a search event listener.
|
||||
// Search events that are expected to happen are added to the queue, and the
|
||||
// listener consumes the queue and ensures that each event it receives is at
|
||||
// the head of the queue.
|
||||
//
|
||||
// Each item in the queue is an object { type, deferred }. type is the
|
||||
// expected search event type. deferred is a Promise.defer() value that is
|
||||
// resolved when the event is consumed.
|
||||
var gExpectedSearchEventQueue = [];
|
||||
|
||||
var gNewEngines = [];
|
||||
|
||||
function runTests() {
|
||||
let oldCurrentEngine = Services.search.currentEngine;
|
||||
|
||||
yield addNewTabPageTab();
|
||||
yield whenSearchInitDone();
|
||||
|
||||
// The tab is removed at the end of the test, so there's no need to remove
|
||||
// this listener at the end of the test.
|
||||
info("Adding search event listener");
|
||||
getContentWindow().addEventListener(SERVICE_EVENT_NAME, searchEventListener);
|
||||
|
||||
let panel = searchPanel();
|
||||
is(panel.state, "closed", "Search panel should be closed initially");
|
||||
|
||||
// The panel's animation often is not finished when the test clicks on panel
|
||||
// children, which makes the test click the wrong children, so disable it.
|
||||
panel.setAttribute("animate", "false");
|
||||
|
||||
// Add the two test engines.
|
||||
let logoEngine = null;
|
||||
yield promiseNewSearchEngine(true).then(engine => {
|
||||
logoEngine = engine;
|
||||
TestRunner.next();
|
||||
});
|
||||
ok(!!logoEngine.getIconURLBySize(...LOGO_LOW_DPI_SIZE),
|
||||
"Sanity check: engine should have 1x logo");
|
||||
ok(!!logoEngine.getIconURLBySize(...LOGO_HIGH_DPI_SIZE),
|
||||
"Sanity check: engine should have 2x logo");
|
||||
|
||||
let noLogoEngine = null;
|
||||
yield promiseNewSearchEngine(false).then(engine => {
|
||||
noLogoEngine = engine;
|
||||
TestRunner.next();
|
||||
});
|
||||
ok(!noLogoEngine.getIconURLBySize(...LOGO_LOW_DPI_SIZE),
|
||||
"Sanity check: engine should not have 1x logo");
|
||||
ok(!noLogoEngine.getIconURLBySize(...LOGO_HIGH_DPI_SIZE),
|
||||
"Sanity check: engine should not have 2x logo");
|
||||
|
||||
// Use the search service to change the current engine to the logo engine.
|
||||
Services.search.currentEngine = logoEngine;
|
||||
yield promiseSearchEvents(["CurrentEngine"]).then(TestRunner.next);
|
||||
checkCurrentEngine(ENGINE_LOGO);
|
||||
|
||||
// Click the logo to open the search panel.
|
||||
yield Promise.all([
|
||||
promisePanelShown(panel),
|
||||
promiseClick(logoImg()),
|
||||
]).then(TestRunner.next);
|
||||
|
||||
// In the search panel, click the no-logo engine. It should become the
|
||||
// current engine.
|
||||
let noLogoBox = null;
|
||||
for (let box of panel.childNodes) {
|
||||
if (box.getAttribute("engine") == noLogoEngine.name) {
|
||||
noLogoBox = box;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(noLogoBox, "Search panel should contain the no-logo engine");
|
||||
yield Promise.all([
|
||||
promiseSearchEvents(["CurrentEngine"]),
|
||||
promiseClick(noLogoBox),
|
||||
]).then(TestRunner.next);
|
||||
|
||||
checkCurrentEngine(ENGINE_NO_LOGO);
|
||||
|
||||
// Switch back to the logo engine.
|
||||
Services.search.currentEngine = logoEngine;
|
||||
yield promiseSearchEvents(["CurrentEngine"]).then(TestRunner.next);
|
||||
checkCurrentEngine(ENGINE_LOGO);
|
||||
|
||||
// Open the panel again.
|
||||
yield Promise.all([
|
||||
promisePanelShown(panel),
|
||||
promiseClick(logoImg()),
|
||||
]).then(TestRunner.next);
|
||||
|
||||
// In the search panel, click the Manage Engines box.
|
||||
let manageBox = $("manage");
|
||||
ok(!!manageBox, "The Manage Engines box should be present in the document");
|
||||
yield Promise.all([
|
||||
promiseManagerOpen(),
|
||||
promiseClick(manageBox),
|
||||
]).then(TestRunner.next);
|
||||
|
||||
// Done. Revert the current engine and remove the new engines.
|
||||
Services.search.currentEngine = oldCurrentEngine;
|
||||
yield promiseSearchEvents(["CurrentEngine"]).then(TestRunner.next);
|
||||
|
||||
let events = [];
|
||||
for (let engine of gNewEngines) {
|
||||
Services.search.removeEngine(engine);
|
||||
events.push("State");
|
||||
}
|
||||
yield promiseSearchEvents(events).then(TestRunner.next);
|
||||
}
|
||||
|
||||
function searchEventListener(event) {
|
||||
info("Got search event " + event.detail.type);
|
||||
let passed = false;
|
||||
let nonempty = gExpectedSearchEventQueue.length > 0;
|
||||
ok(nonempty, "Expected search event queue should be nonempty");
|
||||
if (nonempty) {
|
||||
let { type, deferred } = gExpectedSearchEventQueue.shift();
|
||||
is(event.detail.type, type, "Got expected search event " + type);
|
||||
if (event.detail.type == type) {
|
||||
passed = true;
|
||||
// Let gSearch respond to the event before continuing.
|
||||
executeSoon(() => deferred.resolve());
|
||||
}
|
||||
}
|
||||
if (!passed) {
|
||||
info("Didn't get expected event, stopping the test");
|
||||
getContentWindow().removeEventListener(SERVICE_EVENT_NAME,
|
||||
searchEventListener);
|
||||
// Set next() to a no-op so the test really does stop.
|
||||
TestRunner.next = function () {};
|
||||
TestRunner.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function $(idSuffix) {
|
||||
return getContentDocument().getElementById("newtab-search-" + idSuffix);
|
||||
}
|
||||
|
||||
function promiseSearchEvents(events) {
|
||||
info("Expecting search events: " + events);
|
||||
events = events.map(e => ({ type: e, deferred: Promise.defer() }));
|
||||
gExpectedSearchEventQueue.push(...events);
|
||||
return Promise.all(events.map(e => e.deferred.promise));
|
||||
}
|
||||
|
||||
function promiseNewSearchEngine(withLogo) {
|
||||
let basename = withLogo ? ENGINE_LOGO : ENGINE_NO_LOGO;
|
||||
info("Waiting for engine to be added: " + basename);
|
||||
|
||||
// Wait for the search events triggered by adding the new engine.
|
||||
// engine-added engine-loaded
|
||||
let expectedSearchEvents = ["State", "State"];
|
||||
if (withLogo) {
|
||||
// an engine-changed for each of the two logos
|
||||
expectedSearchEvents.push("State", "State");
|
||||
}
|
||||
let eventPromise = promiseSearchEvents(expectedSearchEvents);
|
||||
|
||||
// Wait for addEngine().
|
||||
let addDeferred = Promise.defer();
|
||||
let url = getRootDirectory(gTestPath) + basename;
|
||||
Services.search.addEngine(url, Ci.nsISearchEngine.TYPE_MOZSEARCH, "", false, {
|
||||
onSuccess: function (engine) {
|
||||
info("Search engine added: " + basename);
|
||||
gNewEngines.push(engine);
|
||||
addDeferred.resolve(engine);
|
||||
},
|
||||
onError: function (errCode) {
|
||||
ok(false, "addEngine failed with error code " + errCode);
|
||||
addDeferred.reject();
|
||||
},
|
||||
});
|
||||
|
||||
// Make a new promise that wraps the previous promises. The only point of
|
||||
// this is to pass the new engine to the yielder via deferred.resolve(),
|
||||
// which is a little nicer than passing an array whose first element is the
|
||||
// new engine.
|
||||
let deferred = Promise.defer();
|
||||
Promise.all([addDeferred.promise, eventPromise]).then(values => {
|
||||
let newEngine = values[0];
|
||||
deferred.resolve(newEngine);
|
||||
}, () => deferred.reject());
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function checkCurrentEngine(basename) {
|
||||
let engine = Services.search.currentEngine;
|
||||
ok(engine.name.contains(basename),
|
||||
"Sanity check: current engine: engine.name=" + engine.name +
|
||||
" basename=" + basename);
|
||||
|
||||
// gSearch.currentEngineName
|
||||
is(gSearch().currentEngineName, engine.name,
|
||||
"currentEngineName: " + engine.name);
|
||||
|
||||
// search bar logo
|
||||
let logoSize = [px * window.devicePixelRatio for (px of LOGO_LOW_DPI_SIZE)];
|
||||
let logoURI = engine.getIconURLBySize(...logoSize);
|
||||
let logo = logoImg();
|
||||
is(logo.hidden, !logoURI,
|
||||
"Logo should be visible iff engine has a logo: " + engine.name);
|
||||
if (logoURI) {
|
||||
is(logo.style.backgroundImage, 'url("' + logoURI + '")', "Logo URI");
|
||||
}
|
||||
|
||||
// "selected" attributes of engines in the panel
|
||||
let panel = searchPanel();
|
||||
for (let engineBox of panel.childNodes) {
|
||||
let engineName = engineBox.getAttribute("engine");
|
||||
if (engineName == engine.name) {
|
||||
is(engineBox.getAttribute("selected"), "true",
|
||||
"Engine box's selected attribute should be true for " +
|
||||
"selected engine: " + engineName);
|
||||
}
|
||||
else {
|
||||
ok(!engineBox.hasAttribute("selected"),
|
||||
"Engine box's selected attribute should be absent for " +
|
||||
"non-selected engine: " + engineName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function promisePanelShown(panel) {
|
||||
let deferred = Promise.defer();
|
||||
info("Waiting for popupshown");
|
||||
panel.addEventListener("popupshown", function onEvent() {
|
||||
panel.removeEventListener("popupshown", onEvent);
|
||||
is(panel.state, "open", "Panel state");
|
||||
executeSoon(() => deferred.resolve());
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function promiseClick(node) {
|
||||
let deferred = Promise.defer();
|
||||
let win = getContentWindow();
|
||||
SimpleTest.waitForFocus(() => {
|
||||
EventUtils.synthesizeMouseAtCenter(node, {}, win);
|
||||
deferred.resolve();
|
||||
}, win);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function promiseManagerOpen() {
|
||||
info("Waiting for the search manager window to open...");
|
||||
let deferred = Promise.defer();
|
||||
let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
winWatcher.registerNotification(function onWin(subj, topic, data) {
|
||||
if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
|
||||
subj.addEventListener("load", function onLoad() {
|
||||
subj.removeEventListener("load", onLoad);
|
||||
if (subj.document.documentURI ==
|
||||
"chrome://browser/content/search/engineManager.xul") {
|
||||
winWatcher.unregisterNotification(onWin);
|
||||
ok(true, "Observed search manager window opened");
|
||||
is(subj.opener, gWindow,
|
||||
"Search engine manager opener should be the chrome browser " +
|
||||
"window containing the newtab page");
|
||||
executeSoon(() => {
|
||||
subj.close();
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function searchPanel() {
|
||||
return $("panel");
|
||||
}
|
||||
|
||||
function logoImg() {
|
||||
return $("logo");
|
||||
}
|
||||
|
||||
function gSearch() {
|
||||
return getContentWindow().gSearch;
|
||||
}
|
|
@ -5,6 +5,10 @@ function runTests() {
|
|||
yield setLinks("0");
|
||||
yield addNewTabPageTab();
|
||||
|
||||
// When gSearch modifies the DOM as it sets itself up, it can prevent the
|
||||
// popup from opening, depending on the timing. Wait until that's done.
|
||||
yield whenSearchInitDone();
|
||||
|
||||
let site = getCell(0).node.querySelector(".newtab-site");
|
||||
site.setAttribute("type", "sponsored");
|
||||
|
||||
|
|
|
@ -25,10 +25,41 @@ let isLinux = ("@mozilla.org/gnome-gconf-service;1" in Cc);
|
|||
let isWindows = ("@mozilla.org/windows-registry-key;1" in Cc);
|
||||
let gWindow = window;
|
||||
|
||||
// The tests assume all three rows of sites are shown, but the window may be too
|
||||
// short to actually show three rows. Resize it if necessary.
|
||||
let requiredInnerHeight =
|
||||
40 + 32 + // undo container + bottom margin
|
||||
44 + 32 + // search bar + bottom margin
|
||||
(3 * (150 + 32)) + // 3 rows * (tile height + title and bottom margin)
|
||||
100; // breathing room
|
||||
|
||||
let oldInnerHeight = null;
|
||||
if (gBrowser.contentWindow.innerHeight < requiredInnerHeight) {
|
||||
oldInnerHeight = gBrowser.contentWindow.innerHeight;
|
||||
info("Changing browser inner height from " + oldInnerHeight + " to " +
|
||||
requiredInnerHeight);
|
||||
gBrowser.contentWindow.innerHeight = requiredInnerHeight;
|
||||
let screenHeight = {};
|
||||
Cc["@mozilla.org/gfx/screenmanager;1"].
|
||||
getService(Ci.nsIScreenManager).
|
||||
primaryScreen.
|
||||
GetAvailRectDisplayPix({}, {}, {}, screenHeight);
|
||||
screenHeight = screenHeight.value;
|
||||
if (screenHeight < gBrowser.contentWindow.outerHeight) {
|
||||
info("Warning: Browser outer height is now " +
|
||||
gBrowser.contentWindow.outerHeight + ", which is larger than the " +
|
||||
"available screen height, " + screenHeight +
|
||||
". That may cause problems.");
|
||||
}
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
while (gWindow.gBrowser.tabs.length > 1)
|
||||
gWindow.gBrowser.removeTab(gWindow.gBrowser.tabs[1]);
|
||||
|
||||
if (oldInnerHeight)
|
||||
gBrowser.contentWindow.innerHeight = oldInnerHeight;
|
||||
|
||||
Services.prefs.clearUserPref(PREF_NEWTAB_ENABLED);
|
||||
Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE);
|
||||
|
||||
|
@ -549,3 +580,35 @@ function whenPagesUpdated(aCallback, aOnlyIfHidden=false) {
|
|||
NewTabUtils.allPages.unregister(page);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits a small amount of time for search events to stop occurring in the
|
||||
* newtab page.
|
||||
*
|
||||
* newtab pages receive some search events around load time that are difficult
|
||||
* to predict. There are two categories of such events: (1) "State" events
|
||||
* triggered by engine notifications like engine-changed, due to the search
|
||||
* service initializing itself on app startup. This can happen when a test is
|
||||
* the first test to run. (2) "State" events triggered by the newtab page
|
||||
* itself when gSearch first sets itself up. newtab preloading makes these a
|
||||
* pain to predict.
|
||||
*/
|
||||
function whenSearchInitDone() {
|
||||
info("Waiting for initial search events...");
|
||||
let numTicks = 0;
|
||||
function reset(event) {
|
||||
info("Got initial search event " + event.detail.type +
|
||||
", waiting for more...");
|
||||
numTicks = 0;
|
||||
}
|
||||
let eventName = "ContentSearchService";
|
||||
getContentWindow().addEventListener(eventName, reset);
|
||||
let interval = window.setInterval(() => {
|
||||
if (++numTicks >= 100) {
|
||||
info("Done waiting for initial search events");
|
||||
window.clearInterval(interval);
|
||||
getContentWindow().removeEventListener(eventName, reset);
|
||||
TestRunner.next();
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>browser_newtab_search searchEngineNoLogo.xml</ShortName>
|
||||
<Url type="text/html" method="GET" template="http://browser-newtab-search.com/nologo" rel="searchform"/>
|
||||
</SearchPlugin>
|
|
@ -599,17 +599,14 @@ function makeURLAbsolute(aBase, aUrl)
|
|||
return makeURI(aUrl, null, makeURI(aBase)).spec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* openNewTabWith: opens a new tab with the given URL.
|
||||
*
|
||||
* @param aURL
|
||||
* The URL to open (as a string).
|
||||
* @param aDocument
|
||||
* The document from which the URL came, or null. This is used to set the
|
||||
* referrer header and to do a security check of whether the document is
|
||||
* allowed to reference the URL. If null, there will be no referrer
|
||||
* header and no security check.
|
||||
* Note this parameter is now ignored. There is no security check & no
|
||||
* referrer header derived from aDocument (null case).
|
||||
* @param aPostData
|
||||
* Form POST data, or null.
|
||||
* @param aEvent
|
||||
|
@ -620,46 +617,40 @@ function makeURLAbsolute(aBase, aUrl)
|
|||
* (e.g., Google's I Feel Lucky) for interpretation. This parameter may
|
||||
* be undefined in which case it is treated as false.
|
||||
* @param [optional] aReferrer
|
||||
* If aDocument is null, then this will be used as the referrer.
|
||||
* There will be no security check.
|
||||
* This will be used as the referrer. There will be no security check.
|
||||
*/
|
||||
function openNewTabWith(aURL, aDocument, aPostData, aEvent,
|
||||
aAllowThirdPartyFixup, aReferrer) {
|
||||
if (aDocument)
|
||||
urlSecurityCheck(aURL, aDocument.nodePrincipal);
|
||||
|
||||
// As in openNewWindowWith(), we want to pass the charset of the
|
||||
// current document over to a new tab.
|
||||
var originCharset = aDocument && aDocument.characterSet;
|
||||
if (!originCharset &&
|
||||
document.documentElement.getAttribute("windowtype") == "navigator:browser")
|
||||
originCharset = window.content.document.characterSet;
|
||||
let originCharset = null;
|
||||
if (document.documentElement.getAttribute("windowtype") == "navigator:browser")
|
||||
originCharset = gBrowser.selectedBrowser.characterSet;
|
||||
|
||||
openLinkIn(aURL, aEvent && aEvent.shiftKey ? "tabshifted" : "tab",
|
||||
{ charset: originCharset,
|
||||
postData: aPostData,
|
||||
allowThirdPartyFixup: aAllowThirdPartyFixup,
|
||||
referrerURI: aDocument ? aDocument.documentURIObject : aReferrer });
|
||||
referrerURI: aReferrer });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param aDocument
|
||||
* Note this parameter is ignored. See openNewTabWith()
|
||||
*/
|
||||
function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, aReferrer) {
|
||||
if (aDocument)
|
||||
urlSecurityCheck(aURL, aDocument.nodePrincipal);
|
||||
|
||||
// if and only if the current window is a browser window and it has a
|
||||
// document with a character set, then extract the current charset menu
|
||||
// setting from the current document and use it to initialize the new browser
|
||||
// window...
|
||||
var originCharset = aDocument && aDocument.characterSet;
|
||||
if (!originCharset &&
|
||||
document.documentElement.getAttribute("windowtype") == "navigator:browser")
|
||||
originCharset = window.content.document.characterSet;
|
||||
// Extract the current charset menu setting from the current document and
|
||||
// use it to initialize the new browser window...
|
||||
let originCharset = null;
|
||||
if (document.documentElement.getAttribute("windowtype") == "navigator:browser")
|
||||
originCharset = gBrowser.selectedBrowser.characterSet;
|
||||
|
||||
openLinkIn(aURL, "window",
|
||||
{ charset: originCharset,
|
||||
postData: aPostData,
|
||||
allowThirdPartyFixup: aAllowThirdPartyFixup,
|
||||
referrerURI: aDocument ? aDocument.documentURIObject : aReferrer });
|
||||
referrerURI: aReferrer });
|
||||
}
|
||||
|
||||
// aCalledFromModal is optional
|
||||
|
|
|
@ -98,6 +98,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "SignInToWebsiteUX",
|
|||
"resource:///modules/SignInToWebsite.jsm");
|
||||
#endif
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContentSearch",
|
||||
"resource:///modules/ContentSearch.jsm");
|
||||
|
||||
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
|
||||
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
|
||||
|
||||
|
@ -497,6 +500,7 @@ BrowserGlue.prototype = {
|
|||
AboutHome.init();
|
||||
SessionStore.init();
|
||||
BrowserUITelemetry.init();
|
||||
ContentSearch.init();
|
||||
|
||||
if (Services.appinfo.browserTabsRemote) {
|
||||
ContentClick.init();
|
||||
|
|
|
@ -65,6 +65,50 @@ function test() {
|
|||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "new tab search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
function doSearch(doc) {
|
||||
// Re-add the listener, and perform a search
|
||||
gBrowser.addProgressListener(listener);
|
||||
doc.getElementById("newtab-search-text").value = "foo";
|
||||
doc.getElementById("newtab-search-submit").click();
|
||||
}
|
||||
|
||||
// load about:newtab, but remove the listener first so it doesn't
|
||||
// get in the way
|
||||
gBrowser.removeProgressListener(listener);
|
||||
gBrowser.loadURI("about:newtab");
|
||||
info("Waiting for about:newtab load");
|
||||
tab.linkedBrowser.addEventListener("load", function load(event) {
|
||||
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
|
||||
event.target.location.href == "about:blank") {
|
||||
info("skipping spurious load event");
|
||||
return;
|
||||
}
|
||||
tab.linkedBrowser.removeEventListener("load", load, true);
|
||||
|
||||
// Observe page setup
|
||||
let win = gBrowser.contentWindow;
|
||||
if (win.gSearch.currentEngineName ==
|
||||
Services.search.currentEngine.name) {
|
||||
doSearch(win.document);
|
||||
}
|
||||
else {
|
||||
info("Waiting for newtab search init");
|
||||
win.addEventListener("ContentSearchService", function done(event) {
|
||||
info("Got newtab search event " + event.detail.type);
|
||||
if (event.detail.type == "State") {
|
||||
win.removeEventListener("ContentSearchService", done);
|
||||
// Let gSearch respond to the event before continuing.
|
||||
executeSoon(() => doSearch(win.document));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "home page search",
|
||||
searchURL: base + "&form=MOZSPG",
|
||||
|
|
|
@ -95,6 +95,50 @@ function test() {
|
|||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "new tab search",
|
||||
searchURL: base,
|
||||
run: function () {
|
||||
function doSearch(doc) {
|
||||
// Re-add the listener, and perform a search
|
||||
gBrowser.addProgressListener(listener);
|
||||
doc.getElementById("newtab-search-text").value = "foo";
|
||||
doc.getElementById("newtab-search-submit").click();
|
||||
}
|
||||
|
||||
// load about:newtab, but remove the listener first so it doesn't
|
||||
// get in the way
|
||||
gBrowser.removeProgressListener(listener);
|
||||
gBrowser.loadURI("about:newtab");
|
||||
info("Waiting for about:newtab load");
|
||||
tab.linkedBrowser.addEventListener("load", function load(event) {
|
||||
if (event.originalTarget != tab.linkedBrowser.contentDocument ||
|
||||
event.target.location.href == "about:blank") {
|
||||
info("skipping spurious load event");
|
||||
return;
|
||||
}
|
||||
tab.linkedBrowser.removeEventListener("load", load, true);
|
||||
|
||||
// Observe page setup
|
||||
let win = gBrowser.contentWindow;
|
||||
if (win.gSearch.currentEngineName ==
|
||||
Services.search.currentEngine.name) {
|
||||
doSearch(win.document);
|
||||
}
|
||||
else {
|
||||
info("Waiting for newtab search init");
|
||||
win.addEventListener("ContentSearchService", function done(event) {
|
||||
info("Got newtab search event " + event.detail.type);
|
||||
if (event.detail.type == "State") {
|
||||
win.removeEventListener("ContentSearchService", done);
|
||||
// Let gSearch respond to the event before continuing.
|
||||
executeSoon(() => doSearch(win.document));
|
||||
}
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "home page search",
|
||||
searchURL: base + "&channel=np&source=hp",
|
||||
|
|
|
@ -286,6 +286,10 @@ let SessionHistoryListener = {
|
|||
return true;
|
||||
},
|
||||
|
||||
OnHistoryReplaceEntry: function (index) {
|
||||
this.collect();
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference
|
||||
|
|
|
@ -369,6 +369,7 @@ HistoryListener.prototype = {
|
|||
OnHistoryGoForward: function(forwardURI) { return true; },
|
||||
OnHistoryGotoIndex: function(index, gotoURI) { return true; },
|
||||
OnHistoryPurge: function(numEntries) { return true; },
|
||||
OnHistoryReplaceEntry: function(index) {},
|
||||
|
||||
OnHistoryReload: function(reloadURI, reloadFlags) {
|
||||
this.callback();
|
||||
|
|
|
@ -2581,6 +2581,12 @@ let SessionStoreInternal = {
|
|||
// Save the index in case we updated it above.
|
||||
tabData.index = activeIndex + 1;
|
||||
|
||||
// In electrolysis, we may need to change the browser's remote
|
||||
// attribute so that it runs in a content process.
|
||||
let activePageData = tabData.entries[activeIndex] || null;
|
||||
let uri = activePageData ? activePageData.url || null : null;
|
||||
tabbrowser.updateBrowserRemoteness(browser, uri);
|
||||
|
||||
// Start a new epoch and include the epoch in the restoreHistory
|
||||
// message. If a message is received that relates to a previous epoch, we
|
||||
// discard it.
|
||||
|
@ -2604,12 +2610,6 @@ let SessionStoreInternal = {
|
|||
pageStyle: tabData.pageStyle || null
|
||||
});
|
||||
|
||||
// In electrolysis, we may need to change the browser's remote
|
||||
// attribute so that it runs in a content process.
|
||||
let activePageData = tabData.entries[activeIndex] || null;
|
||||
let uri = activePageData ? activePageData.url || null : null;
|
||||
tabbrowser.updateBrowserRemoteness(browser, uri);
|
||||
|
||||
browser.messageManager.sendAsyncMessage("SessionStore:restoreHistory",
|
||||
{tabData: tabData, epoch: epoch});
|
||||
|
||||
|
|
|
@ -220,15 +220,15 @@ add_task(function test_pushstate_replacestate() {
|
|||
is(entries[1].url, "http://example.com/test-entry/", "url is correct");
|
||||
|
||||
// Disabled until replaceState invalidation is supported. See Bug 967028.
|
||||
// browser.messageManager.
|
||||
// sendAsyncMessage("ss-test:historyReplaceState", {url: 'test-entry2/'});
|
||||
// yield promiseContentMessage(browser, "ss-test:historyReplaceState");
|
||||
browser.messageManager.
|
||||
sendAsyncMessage("ss-test:historyReplaceState", {url: 'test-entry2/'});
|
||||
yield promiseContentMessage(browser, "ss-test:historyReplaceState");
|
||||
|
||||
// // Check that we have modified the history entry.
|
||||
// SyncHandlers.get(browser).flush();
|
||||
// let {entries} = JSON.parse(ss.getTabState(tab));
|
||||
// is(entries.length, 2, "there is still two shistory entries");
|
||||
// is(entries[1].url, "http://example.com/test-entry/test-entry2/", "url is correct");
|
||||
// Check that we have modified the history entry.
|
||||
SyncHandlers.get(browser).flush();
|
||||
let {entries} = JSON.parse(ss.getTabState(tab));
|
||||
is(entries.length, 2, "there is still two shistory entries");
|
||||
is(entries[1].url, "http://example.com/test-entry/test-entry2/", "url is correct");
|
||||
|
||||
// Cleanup.
|
||||
gBrowser.removeTab(tab);
|
||||
|
|
|
@ -9,8 +9,6 @@
|
|||
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-break-on-last-line-of-script-on-reload.html";
|
||||
const CODE_URL = EXAMPLE_URL + "code_breakpoints-break-on-last-line-of-script-on-reload.js";
|
||||
|
||||
const { promiseInvoke } = require("devtools/async-utils");
|
||||
|
||||
function test() {
|
||||
let gPanel, gDebugger, gThreadClient, gEvents;
|
||||
|
||||
|
@ -59,15 +57,15 @@ function test() {
|
|||
|
||||
// And we should hit the breakpoints as we resume.
|
||||
yield promise.all([
|
||||
doResume(),
|
||||
doResume(gPanel),
|
||||
waitForCaretAndScopes(gPanel, 3)
|
||||
]);
|
||||
yield promise.all([
|
||||
doResume(),
|
||||
doResume(gPanel),
|
||||
waitForCaretAndScopes(gPanel, 4)
|
||||
]);
|
||||
yield promise.all([
|
||||
doResume(),
|
||||
doResume(gPanel),
|
||||
waitForCaretAndScopes(gPanel, 5)
|
||||
]);
|
||||
|
||||
|
@ -90,23 +88,6 @@ function test() {
|
|||
});
|
||||
});
|
||||
|
||||
function rdpInvoke(obj, method) {
|
||||
return promiseInvoke(obj, method)
|
||||
.then(({error, message }) => {
|
||||
if (error) {
|
||||
throw new Error(error + ": " + message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function doResume() {
|
||||
return rdpInvoke(gThreadClient, gThreadClient.resume);
|
||||
}
|
||||
|
||||
function doInterrupt() {
|
||||
return rdpInvoke(gThreadClient, gThreadClient.interrupt);
|
||||
}
|
||||
|
||||
function setBreakpoint(location) {
|
||||
let deferred = promise.defer();
|
||||
gThreadClient.setBreakpoint(location, ({ error, message }, bpClient) => {
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that pretty printing when the debugger is paused
|
||||
* does not switch away from the selected source.
|
||||
* Test that pretty printing when the debugger is paused does not switch away
|
||||
* from the selected source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_pretty-print-on-paused.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gSources;
|
||||
let gTab, gDebuggee, gPanel, gDebugger, gThreadClient, gSources;
|
||||
|
||||
let gSecondSourceLabel = "code_ugly-2.js";
|
||||
const SECOND_SOURCE_VALUE = EXAMPLE_URL + "code_ugly-2.js";
|
||||
|
||||
function test(){
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
|
@ -19,63 +18,50 @@ function test(){
|
|||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gThreadClient = gDebugger.gThreadClient;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
gPanel.addBreakpoint({ url: gSources.values[0], line: 6 });
|
||||
Task.spawn(function* () {
|
||||
try {
|
||||
yield ensureSourceIs(gPanel, "code_script-switching-02.js", true);
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6)
|
||||
.then(testPaused)
|
||||
.then(() => {
|
||||
// Switch to the second source.
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedIndex = 1;
|
||||
return finished;
|
||||
})
|
||||
.then(testSecondSourceIsSelected)
|
||||
.then(() => {
|
||||
const finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
clickPrettyPrintButton();
|
||||
testProgressBarShown();
|
||||
return finished;
|
||||
})
|
||||
.then(testSecondSourceIsStillSelected)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
|
||||
})
|
||||
yield doInterrupt(gPanel);
|
||||
yield rdpInvoke(gThreadClient, gThreadClient.setBreakpoint, {
|
||||
url: gSources.selectedValue,
|
||||
line: 6
|
||||
});
|
||||
yield doResume(gPanel);
|
||||
|
||||
gDebuggee.secondCall();
|
||||
const bpHit = waitForCaretAndScopes(gPanel, 6);
|
||||
// Get the debuggee call off this tick so that we aren't accidentally
|
||||
// blocking the yielding of bpHit which causes a deadlock.
|
||||
executeSoon(() => gDebuggee.secondCall());
|
||||
yield bpHit;
|
||||
|
||||
info("Switch to the second source.");
|
||||
const sourceShown = waitForSourceShown(gPanel, SECOND_SOURCE_VALUE);
|
||||
gSources.selectedValue = SECOND_SOURCE_VALUE;
|
||||
yield sourceShown;
|
||||
|
||||
info("Pretty print the source.");
|
||||
const prettyPrinted = waitForSourceShown(gPanel, SECOND_SOURCE_VALUE);
|
||||
gDebugger.document.getElementById("pretty-print").click();
|
||||
yield prettyPrinted;
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
} catch (e) {
|
||||
DevToolsUtils.reportException("browser_dbg_pretty-print-on-paused.js", e);
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testPaused() {
|
||||
is(gDebugger.gThreadClient.paused, true,
|
||||
"The thread should be paused");
|
||||
}
|
||||
|
||||
function testSecondSourceIsSelected() {
|
||||
ok(gSources.containsValue(EXAMPLE_URL + gSecondSourceLabel),
|
||||
"The second source should be selected.");
|
||||
}
|
||||
|
||||
function clickPrettyPrintButton() {
|
||||
gDebugger.document.getElementById("pretty-print").click();
|
||||
}
|
||||
|
||||
function testProgressBarShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, 2, "The progress bar should be shown");
|
||||
}
|
||||
|
||||
function testSecondSourceIsStillSelected() {
|
||||
ok(gSources.containsValue(EXAMPLE_URL + gSecondSourceLabel),
|
||||
"The second source should still be selected.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gThreadClient = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
|
|
@ -22,6 +22,7 @@ let { BrowserToolboxProcess } = Cu.import("resource:///modules/devtools/ToolboxP
|
|||
let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
|
||||
let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
|
||||
let { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {});
|
||||
const { promiseInvoke } = require("devtools/async-utils");
|
||||
let TargetFactory = devtools.TargetFactory;
|
||||
let Toolbox = devtools.Toolbox;
|
||||
|
||||
|
@ -856,3 +857,23 @@ function attachAddonActorForUrl(aClient, aUrl) {
|
|||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function rdpInvoke(aClient, aMethod, ...args) {
|
||||
return promiseInvoke(aClient, aMethod, ...args)
|
||||
.then(({error, message }) => {
|
||||
if (error) {
|
||||
throw new Error(error + ": " + message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function doResume(aPanel) {
|
||||
const threadClient = aPanel.panelWin.gThreadClient;
|
||||
return rdpInvoke(threadClient, threadClient.resume);
|
||||
}
|
||||
|
||||
function doInterrupt(aPanel) {
|
||||
const threadClient = aPanel.panelWin.gThreadClient;
|
||||
return rdpInvoke(threadClient, threadClient.interrupt);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/* 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 gcli = require("gcli/index");
|
||||
const EventEmitter = require("devtools/toolkit/event-emitter");
|
||||
const eventEmitter = new EventEmitter();
|
||||
|
||||
let { Eyedropper, EyedropperManager } = require("devtools/eyedropper/eyedropper");
|
||||
|
||||
/**
|
||||
* 'eyedropper' command
|
||||
*/
|
||||
exports.items = [{
|
||||
name: "eyedropper",
|
||||
description: gcli.lookup("eyedropperDesc"),
|
||||
manual: gcli.lookup("eyedropperManual"),
|
||||
buttonId: "command-button-eyedropper",
|
||||
buttonClass: "command-button command-button-invertable",
|
||||
tooltipText: gcli.lookup("eyedropperTooltip"),
|
||||
state: {
|
||||
isChecked: function(target) {
|
||||
let chromeWindow = target.tab.ownerDocument.defaultView;
|
||||
let dropper = EyedropperManager.getInstance(chromeWindow);
|
||||
if (dropper) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onChange: function(target, changeHandler) {
|
||||
eventEmitter.on("changed", changeHandler);
|
||||
},
|
||||
offChange: function(target, changeHandler) {
|
||||
eventEmitter.off("changed", changeHandler);
|
||||
},
|
||||
},
|
||||
exec: function(args, context) {
|
||||
let chromeWindow = context.environment.chromeWindow;
|
||||
let target = context.environment.target;
|
||||
|
||||
let dropper = EyedropperManager.createInstance(chromeWindow);
|
||||
dropper.open();
|
||||
|
||||
eventEmitter.emit("changed", target.tab);
|
||||
|
||||
dropper.once("destroy", () => {
|
||||
eventEmitter.emit("changed", target.tab);
|
||||
});
|
||||
}
|
||||
}];
|
|
@ -48,6 +48,40 @@ const CLOSE_DELAY = 750;
|
|||
const HEX_BOX_WIDTH = CANVAS_WIDTH + CANVAS_OFFSET * 2;
|
||||
const HSL_BOX_WIDTH = 158;
|
||||
|
||||
/**
|
||||
* Manage instances of eyedroppers for windows. Registering here isn't
|
||||
* necessary for creating an eyedropper, but can be used for testing.
|
||||
*/
|
||||
let EyedropperManager = {
|
||||
_instances: new WeakMap(),
|
||||
|
||||
getInstance: function(chromeWindow) {
|
||||
return this._instances.get(chromeWindow);
|
||||
},
|
||||
|
||||
createInstance: function(chromeWindow) {
|
||||
let dropper = this.getInstance(chromeWindow);
|
||||
if (dropper) {
|
||||
return dropper;
|
||||
}
|
||||
|
||||
dropper = new Eyedropper(chromeWindow);
|
||||
this._instances.set(chromeWindow, dropper);
|
||||
|
||||
dropper.on("destroy", () => {
|
||||
this.deleteInstance(chromeWindow);
|
||||
});
|
||||
|
||||
return dropper;
|
||||
},
|
||||
|
||||
deleteInstance: function(chromeWindow) {
|
||||
this._instances.delete(chromeWindow);
|
||||
}
|
||||
}
|
||||
|
||||
exports.EyedropperManager = EyedropperManager;
|
||||
|
||||
/**
|
||||
* Eyedropper widget. Once opened, shows zoomed area above current pixel and
|
||||
* displays the color value of the center pixel. Clicking on the window will
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
JS_MODULES_PATH = 'modules/devtools/eyedropper'
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'commands.js',
|
||||
'eyedropper.js'
|
||||
]
|
||||
|
||||
|
|
|
@ -7,3 +7,4 @@ support-files =
|
|||
|
||||
[browser_eyedropper_basic.js]
|
||||
skip-if = os == "win" && debug # bug 963492
|
||||
[browser_eyedropper_cmd.js]
|
||||
|
|
|
@ -62,14 +62,3 @@ function inspectPage(dropper, click=true) {
|
|||
function pressESC() {
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
function dropperLoaded(dropper) {
|
||||
if (dropper.loaded) {
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
let deferred = promise.defer();
|
||||
dropper.once("load", deferred.resolve);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the eyedropper command works
|
||||
|
||||
const TESTCASE_URI = TEST_BASE + "color-block.html";
|
||||
const DIV_COLOR = "#0000FF";
|
||||
|
||||
function test() {
|
||||
return Task.spawn(spawnTest).then(finish, helpers.handleError);
|
||||
}
|
||||
|
||||
function spawnTest() {
|
||||
let options = yield helpers.openTab(TESTCASE_URI);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
yield helpers.audit(options, [
|
||||
{
|
||||
setup: "eyedropper",
|
||||
check: {
|
||||
input: "eyedropper"
|
||||
},
|
||||
exec: { output: "" }
|
||||
},
|
||||
]);
|
||||
|
||||
yield inspectAndWaitForCopy();
|
||||
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
}
|
||||
|
||||
function inspectAndWaitForCopy() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
waitForClipboard(DIV_COLOR, () => {
|
||||
inspectPage(); // setup: inspect the page
|
||||
}, deferred.resolve, deferred.reject);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function inspectPage() {
|
||||
let target = content.document.getElementById("test");
|
||||
let win = content.window;
|
||||
|
||||
EventUtils.synthesizeMouse(target, 20, 20, { type: "mousemove" }, win);
|
||||
|
||||
let dropper = EyedropperManager.getInstance(window);
|
||||
|
||||
return dropperLoaded(dropper).then(() => {
|
||||
EventUtils.synthesizeMouse(target, 30, 30, { type: "mousemove" }, win);
|
||||
|
||||
EventUtils.synthesizeMouse(target, 30, 30, {}, win);
|
||||
});
|
||||
}
|
|
@ -4,10 +4,11 @@
|
|||
const TEST_BASE = "chrome://mochitests/content/browser/browser/devtools/eyedropper/test/";
|
||||
const TEST_HOST = 'mochi.test:8888';
|
||||
|
||||
const promise = Cu.import("resource://gre/modules/devtools/deprecated-sync-thenables.js").Promise;
|
||||
const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
|
||||
const { Eyedropper } = require("devtools/eyedropper/eyedropper");
|
||||
let { devtools } = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||
const { Eyedropper, EyedropperManager } = devtools.require("devtools/eyedropper/eyedropper");
|
||||
|
||||
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
||||
Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
|
@ -35,3 +36,10 @@ function addTab(uri) {
|
|||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function dropperLoaded(dropper) {
|
||||
if (dropper.loaded) {
|
||||
return promise.resolve();
|
||||
}
|
||||
return dropper.once("load");
|
||||
}
|
||||
|
|
|
@ -573,7 +573,8 @@ Toolbox.prototype = {
|
|||
"command-button-responsive",
|
||||
"command-button-paintflashing",
|
||||
"command-button-tilt",
|
||||
"command-button-scratchpad"
|
||||
"command-button-scratchpad",
|
||||
"command-button-eyedropper"
|
||||
].map(id => {
|
||||
let button = this.doc.getElementById(id);
|
||||
// Some buttons may not exist inside of Browser Toolbox
|
||||
|
|
|
@ -128,6 +128,7 @@ Tools.inspector = {
|
|||
commands: [
|
||||
"devtools/resize-commands",
|
||||
"devtools/inspector/inspector-commands",
|
||||
"devtools/eyedropper/commands.js"
|
||||
],
|
||||
|
||||
preventClosingOnKey: true,
|
||||
|
|
|
@ -693,7 +693,7 @@ Tooltip.prototype = {
|
|||
let iframe = this.doc.createElementNS(XHTML_NS, "iframe");
|
||||
iframe.setAttribute("transparent", true);
|
||||
iframe.setAttribute("width", "210");
|
||||
iframe.setAttribute("height", "220");
|
||||
iframe.setAttribute("height", "216");
|
||||
iframe.setAttribute("flex", "1");
|
||||
iframe.setAttribute("class", "devtools-tooltip-iframe");
|
||||
|
||||
|
|
|
@ -19,6 +19,6 @@
|
|||
</head>
|
||||
<body role="application">
|
||||
<div id="spectrum"></div>
|
||||
<button id="eyedropper-button"></button>
|
||||
<div id="eyedropper-button"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -3,17 +3,40 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#eyedropper-button {
|
||||
background: url("chrome://browser/skin/devtools/eyedropper-black.png") no-repeat center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
-moz-margin-start: 6px;
|
||||
border: 1px solid #ccc;
|
||||
background-image: url("chrome://browser/skin/devtools/command-eyedropper.png");
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-size: 64px 16px;
|
||||
background-position: 0 center;
|
||||
background-repeat: no-repeat;
|
||||
-moz-margin-start: 5px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.theme-light #eyedropper-button {
|
||||
filter: url(chrome://browser/skin/devtools/filters.svg#invert);
|
||||
border: 1px solid #AAA;
|
||||
}
|
||||
|
||||
.theme-dark #eyedropper-button {
|
||||
filter: url(chrome://browser/skin/devtools/filters.svg#colorpicker-invert);
|
||||
border: 1px solid #444;
|
||||
}
|
||||
|
||||
#eyedropper-button:hover {
|
||||
background-position: -16px center;
|
||||
}
|
||||
#eyedropper-button:hover:active {
|
||||
background-position: -32px center;
|
||||
}
|
||||
#eyedropper-button[checked=true] {
|
||||
background-position: -48px center;
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#eyedropper-button {
|
||||
background-image: url("chrome://browser/skin/devtools/command-eyedropper@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
/* Mix-in classes */
|
||||
|
|
|
@ -170,7 +170,6 @@
|
|||
@BINPATH@/components/composer.xpt
|
||||
@BINPATH@/components/content_base.xpt
|
||||
@BINPATH@/components/content_events.xpt
|
||||
@BINPATH@/components/content_canvas.xpt
|
||||
@BINPATH@/components/content_htmldoc.xpt
|
||||
@BINPATH@/components/content_html.xpt
|
||||
#ifdef MOZ_WEBRTC
|
||||
|
|
|
@ -430,6 +430,30 @@ FunctionEnd
|
|||
WriteRegStr SHCTX "$0\.xhtml" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
; Only add .oga if it's not present
|
||||
${CheckIfRegistryKeyExists} "$0" ".oga" $7
|
||||
${If} $7 == "false"
|
||||
WriteRegStr SHCTX "$0\.oga" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
; Only add .ogg if it's not present
|
||||
${CheckIfRegistryKeyExists} "$0" ".ogg" $7
|
||||
${If} $7 == "false"
|
||||
WriteRegStr SHCTX "$0\.ogg" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
; Only add .ogv if it's not present
|
||||
${CheckIfRegistryKeyExists} "$0" ".ogv" $7
|
||||
${If} $7 == "false"
|
||||
WriteRegStr SHCTX "$0\.ogv" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
; Only add .pdf if it's not present
|
||||
${CheckIfRegistryKeyExists} "$0" ".pdf" $7
|
||||
${If} $7 == "false"
|
||||
WriteRegStr SHCTX "$0\.pdf" "" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
; Only add webm if it's not present
|
||||
${CheckIfRegistryKeyExists} "$0" ".webm" $7
|
||||
${If} $7 == "false"
|
||||
|
|
|
@ -324,6 +324,10 @@ Section "Uninstall"
|
|||
${un.RegCleanFileHandler} ".shtml" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".xht" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".xhtml" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".oga" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".ogg" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".ogv" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".pdf" "FirefoxHTML"
|
||||
${un.RegCleanFileHandler} ".webm" "FirefoxHTML"
|
||||
${EndIf}
|
||||
|
||||
|
|
|
@ -165,6 +165,20 @@ inspectNodeDesc=CSS selector
|
|||
# on what it does.
|
||||
inspectNodeManual=A CSS selector for use with document.querySelector which identifies a single element
|
||||
|
||||
# LOCALIZATION NOTE (eyedropperDesc) A very short description of the 'eyedropper'
|
||||
# command. See eyedropperManual for a fuller description of what it does. This
|
||||
# string is designed to be shown in a menu alongside the command name, which
|
||||
# is why it should be as short as possible.
|
||||
eyedropperDesc=Grab a color from the page
|
||||
|
||||
# LOCALIZATION NOTE (eyedropperManual) A fuller description of the 'eyedropper'
|
||||
# command, displayed when the user asks for help on what it does.
|
||||
eyedropperManual=Open a panel that magnifies an area of page to inspect pixels and copy color values
|
||||
|
||||
# LOCALIZATION NOTE (eyedropperTooltip) A string displayed as the
|
||||
# tooltip of button in devtools toolbox which toggles the Eyedropper tool.
|
||||
eyedropperTooltip=Grab a color from the page
|
||||
|
||||
# LOCALIZATION NOTE (tiltDesc) A very short description of the 'tilt'
|
||||
# command. See tiltManual for a fuller description of what it does. This
|
||||
# string is designed to be shown in a menu alongside the command name, which
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"ContentSearch",
|
||||
];
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const INBOUND_MESSAGE = "ContentSearch";
|
||||
const OUTBOUND_MESSAGE = INBOUND_MESSAGE;
|
||||
|
||||
/**
|
||||
* ContentSearch receives messages named INBOUND_MESSAGE and sends messages
|
||||
* named OUTBOUND_MESSAGE. The data of each message is expected to look like
|
||||
* { type, data }. type is the message's type (or subtype if you consider the
|
||||
* type of the message itself to be INBOUND_MESSAGE), and data is data that is
|
||||
* specific to the type.
|
||||
*
|
||||
* Inbound messages have the following types:
|
||||
*
|
||||
* GetState
|
||||
* Retrieves the current search engine state.
|
||||
* data: null
|
||||
* ManageEngines
|
||||
* Opens the search engine management window.
|
||||
* data: null
|
||||
* Search
|
||||
* Performs a search.
|
||||
* data: an object { engineName, searchString, whence }
|
||||
* SetCurrentEngine
|
||||
* Sets the current engine.
|
||||
* data: the name of the engine
|
||||
*
|
||||
* Outbound messages have the following types:
|
||||
*
|
||||
* CurrentEngine
|
||||
* Sent when the current engine changes.
|
||||
* data: see _currentEngineObj
|
||||
* State
|
||||
* Sent in reply to GetState and when the state changes.
|
||||
* data: see _currentStateObj
|
||||
*/
|
||||
|
||||
this.ContentSearch = {
|
||||
|
||||
init: function () {
|
||||
Cc["@mozilla.org/globalmessagemanager;1"].
|
||||
getService(Ci.nsIMessageListenerManager).
|
||||
addMessageListener(INBOUND_MESSAGE, this);
|
||||
Services.obs.addObserver(this, "browser-search-engine-modified", false);
|
||||
},
|
||||
|
||||
receiveMessage: function (msg) {
|
||||
let methodName = "on" + msg.data.type;
|
||||
if (methodName in this) {
|
||||
this[methodName](msg, msg.data.data);
|
||||
}
|
||||
},
|
||||
|
||||
onGetState: function (msg, data) {
|
||||
this._reply(msg, "State", this._currentStateObj());
|
||||
},
|
||||
|
||||
onSearch: function (msg, data) {
|
||||
let expectedDataProps = [
|
||||
"engineName",
|
||||
"searchString",
|
||||
"whence",
|
||||
];
|
||||
for (let prop of expectedDataProps) {
|
||||
if (!(prop in data)) {
|
||||
Cu.reportError("Message data missing required property: " + prop);
|
||||
return;
|
||||
}
|
||||
}
|
||||
let browserWin = msg.target.ownerDocument.defaultView;
|
||||
let engine = Services.search.getEngineByName(data.engineName);
|
||||
browserWin.BrowserSearch.recordSearchInHealthReport(engine, data.whence);
|
||||
let submission = engine.getSubmission(data.searchString, "", data.whence);
|
||||
browserWin.loadURI(submission.uri.spec, null, submission.postData);
|
||||
},
|
||||
|
||||
onSetCurrentEngine: function (msg, data) {
|
||||
Services.search.currentEngine = Services.search.getEngineByName(data);
|
||||
},
|
||||
|
||||
onManageEngines: function (msg, data) {
|
||||
let browserWin = msg.target.ownerDocument.defaultView;
|
||||
browserWin.BrowserSearch.searchBar.openManager(null);
|
||||
},
|
||||
|
||||
observe: function (subj, topic, data) {
|
||||
switch (topic) {
|
||||
case "browser-search-engine-modified":
|
||||
if (data == "engine-current") {
|
||||
this._broadcast("CurrentEngine", this._currentEngineObj());
|
||||
}
|
||||
else if (data != "engine-default") {
|
||||
// engine-default is always sent with engine-current and isn't otherwise
|
||||
// relevant to content searches.
|
||||
this._broadcast("State", this._currentStateObj());
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
_reply: function (msg, type, data) {
|
||||
msg.target.messageManager.sendAsyncMessage(...this._msgArgs(type, data));
|
||||
},
|
||||
|
||||
_broadcast: function (type, data) {
|
||||
Cc["@mozilla.org/globalmessagemanager;1"].
|
||||
getService(Ci.nsIMessageListenerManager).
|
||||
broadcastAsyncMessage(...this._msgArgs(type, data));
|
||||
},
|
||||
|
||||
_msgArgs: function (type, data) {
|
||||
return [OUTBOUND_MESSAGE, {
|
||||
type: type,
|
||||
data: data,
|
||||
}];
|
||||
},
|
||||
|
||||
_currentStateObj: function () {
|
||||
return {
|
||||
engines: Services.search.getVisibleEngines().map(engine => {
|
||||
return {
|
||||
name: engine.name,
|
||||
iconURI: engine.getIconURLBySize(16, 16),
|
||||
};
|
||||
}),
|
||||
currentEngine: this._currentEngineObj(),
|
||||
};
|
||||
},
|
||||
|
||||
_currentEngineObj: function () {
|
||||
return {
|
||||
name: Services.search.currentEngine.name,
|
||||
logoURI: Services.search.currentEngine.getIconURLBySize(65, 26),
|
||||
logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52),
|
||||
};
|
||||
},
|
||||
};
|
|
@ -11,6 +11,7 @@ EXTRA_JS_MODULES += [
|
|||
'BrowserUITelemetry.jsm',
|
||||
'ContentClick.jsm',
|
||||
'ContentLinkHandler.jsm',
|
||||
'ContentSearch.jsm',
|
||||
'CustomizationTabPreloader.jsm',
|
||||
'Feeds.jsm',
|
||||
'NetworkPrioritizer.jsm',
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
head.js
|
||||
uitour.*
|
||||
contentSearch.js
|
||||
image.png
|
||||
uitour.*
|
||||
|
||||
[browser_BrowserUITelemetry_buckets.js]
|
||||
[browser_ContentSearch.js]
|
||||
[browser_NetworkPrioritizer.js]
|
||||
skip-if = e10s # Bug 666804 - Support NetworkPrioritizer in e10s
|
||||
[browser_SignInToWebsite.js]
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
/* 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 TEST_MSG = "ContentSearchTest";
|
||||
const CONTENT_SEARCH_MSG = "ContentSearch";
|
||||
const TEST_CONTENT_SCRIPT_BASENAME = "contentSearch.js";
|
||||
|
||||
function generatorTest() {
|
||||
// nextStep() drives the iterator returned by this function. This function's
|
||||
// iterator in turn drives the iterator of each test below.
|
||||
let currentTestIter = yield startNextTest();
|
||||
let arg = undefined;
|
||||
while (currentTestIter) {
|
||||
try {
|
||||
currentTestIter.send(arg);
|
||||
arg = yield null;
|
||||
}
|
||||
catch (err if err instanceof StopIteration) {
|
||||
currentTestIter = yield startNextTest();
|
||||
arg = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function startNextTest() {
|
||||
if (!gTests.length) {
|
||||
setTimeout(() => nextStep(null), 0);
|
||||
return;
|
||||
}
|
||||
let nextTestGen = gTests.shift();
|
||||
let nextTestIter = nextTestGen();
|
||||
addTab(() => {
|
||||
info("Starting test " + nextTestGen.name);
|
||||
nextStep(nextTestIter);
|
||||
});
|
||||
}
|
||||
|
||||
function addTest(testGen) {
|
||||
gTests.push(testGen);
|
||||
}
|
||||
|
||||
var gTests = [];
|
||||
var gMsgMan;
|
||||
|
||||
addTest(function GetState() {
|
||||
gMsgMan.sendAsyncMessage(TEST_MSG, {
|
||||
type: "GetState",
|
||||
});
|
||||
let msg = yield waitForTestMsg("State");
|
||||
checkMsg(msg, {
|
||||
type: "State",
|
||||
data: currentStateObj(),
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function SetCurrentEngine() {
|
||||
let newCurrentEngine = null;
|
||||
let oldCurrentEngine = Services.search.currentEngine;
|
||||
let engines = Services.search.getVisibleEngines();
|
||||
for (let engine of engines) {
|
||||
if (engine != oldCurrentEngine) {
|
||||
newCurrentEngine = engine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!newCurrentEngine) {
|
||||
info("Couldn't find a non-selected search engine, " +
|
||||
"skipping this part of the test");
|
||||
return;
|
||||
}
|
||||
gMsgMan.sendAsyncMessage(TEST_MSG, {
|
||||
type: "SetCurrentEngine",
|
||||
data: newCurrentEngine.name,
|
||||
});
|
||||
Services.obs.addObserver(function obs(subj, topic, data) {
|
||||
info("Test observed " + data);
|
||||
if (data == "engine-current") {
|
||||
ok(true, "Test observed engine-current");
|
||||
Services.obs.removeObserver(obs, "browser-search-engine-modified", false);
|
||||
nextStep();
|
||||
}
|
||||
}, "browser-search-engine-modified", false);
|
||||
info("Waiting for test to observe engine-current...");
|
||||
waitForTestMsg("CurrentEngine");
|
||||
let maybeMsg1 = yield null;
|
||||
let maybeMsg2 = yield null;
|
||||
let msg = maybeMsg1 || maybeMsg2;
|
||||
ok(!!msg,
|
||||
"Sanity check: One of the yields is for waitForTestMsg and should have " +
|
||||
"therefore produced a message object");
|
||||
checkMsg(msg, {
|
||||
type: "CurrentEngine",
|
||||
data: currentEngineObj(newCurrentEngine),
|
||||
});
|
||||
|
||||
Services.search.currentEngine = oldCurrentEngine;
|
||||
let msg = yield waitForTestMsg("CurrentEngine");
|
||||
checkMsg(msg, {
|
||||
type: "CurrentEngine",
|
||||
data: currentEngineObj(oldCurrentEngine),
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function ManageEngines() {
|
||||
gMsgMan.sendAsyncMessage(TEST_MSG, {
|
||||
type: "ManageEngines",
|
||||
});
|
||||
let winWatcher = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIWindowWatcher);
|
||||
winWatcher.registerNotification(function onOpen(subj, topic, data) {
|
||||
if (topic == "domwindowopened" && subj instanceof Ci.nsIDOMWindow) {
|
||||
subj.addEventListener("load", function onLoad() {
|
||||
subj.removeEventListener("load", onLoad);
|
||||
if (subj.document.documentURI ==
|
||||
"chrome://browser/content/search/engineManager.xul") {
|
||||
winWatcher.unregisterNotification(onOpen);
|
||||
ok(true, "Observed search manager window open");
|
||||
is(subj.opener, window,
|
||||
"Search engine manager opener should be this chrome window");
|
||||
subj.close();
|
||||
nextStep();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
info("Waiting for search engine manager window to open...");
|
||||
yield null;
|
||||
});
|
||||
|
||||
addTest(function modifyEngine() {
|
||||
let engine = Services.search.currentEngine;
|
||||
let oldAlias = engine.alias;
|
||||
engine.alias = "ContentSearchTest";
|
||||
let msg = yield waitForTestMsg("State");
|
||||
checkMsg(msg, {
|
||||
type: "State",
|
||||
data: currentStateObj(),
|
||||
});
|
||||
engine.alias = oldAlias;
|
||||
msg = yield waitForTestMsg("State");
|
||||
checkMsg(msg, {
|
||||
type: "State",
|
||||
data: currentStateObj(),
|
||||
});
|
||||
});
|
||||
|
||||
addTest(function search() {
|
||||
let engine = Services.search.currentEngine;
|
||||
let data = {
|
||||
engineName: engine.name,
|
||||
searchString: "ContentSearchTest",
|
||||
whence: "ContentSearchTest",
|
||||
};
|
||||
gMsgMan.sendAsyncMessage(TEST_MSG, {
|
||||
type: "Search",
|
||||
data: data,
|
||||
});
|
||||
let submissionURL =
|
||||
engine.getSubmission(data.searchString, "", data.whence).uri.spec;
|
||||
let listener = {
|
||||
onStateChange: function (webProg, req, flags, status) {
|
||||
let url = req.originalURI.spec;
|
||||
info("onStateChange " + url);
|
||||
let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
|
||||
Ci.nsIWebProgressListener.STATE_START;
|
||||
if ((flags & docStart) && webProg.isTopLevel && url == submissionURL) {
|
||||
gBrowser.removeProgressListener(listener);
|
||||
ok(true, "Search URL loaded");
|
||||
req.cancel(Components.results.NS_ERROR_FAILURE);
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
};
|
||||
gBrowser.addProgressListener(listener);
|
||||
info("Waiting for search URL to load: " + submissionURL);
|
||||
yield null;
|
||||
});
|
||||
|
||||
function checkMsg(actualMsg, expectedMsgData) {
|
||||
SimpleTest.isDeeply(actualMsg.data, expectedMsgData, "Checking message");
|
||||
}
|
||||
|
||||
function waitForMsg(name, type, callback) {
|
||||
info("Waiting for " + name + " message " + type + "...");
|
||||
gMsgMan.addMessageListener(name, function onMsg(msg) {
|
||||
info("Received " + name + " message " + msg.data.type + "\n");
|
||||
if (msg.data.type == type) {
|
||||
gMsgMan.removeMessageListener(name, onMsg);
|
||||
(callback || nextStep)(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function waitForTestMsg(type, callback) {
|
||||
waitForMsg(TEST_MSG, type, callback);
|
||||
}
|
||||
|
||||
function addTab(onLoad) {
|
||||
let tab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.linkedBrowser.addEventListener("load", function load() {
|
||||
tab.removeEventListener("load", load, true);
|
||||
let url = getRootDirectory(gTestPath) + TEST_CONTENT_SCRIPT_BASENAME;
|
||||
gMsgMan = tab.linkedBrowser.messageManager;
|
||||
gMsgMan.sendAsyncMessage(CONTENT_SEARCH_MSG, {
|
||||
type: "AddToWhitelist",
|
||||
data: ["about:blank"],
|
||||
});
|
||||
waitForMsg(CONTENT_SEARCH_MSG, "AddToWhitelistAck", () => {
|
||||
gMsgMan.loadFrameScript(url, false);
|
||||
onLoad();
|
||||
});
|
||||
}, true);
|
||||
registerCleanupFunction(() => gBrowser.removeTab(tab));
|
||||
}
|
||||
|
||||
function currentStateObj() {
|
||||
return {
|
||||
engines: Services.search.getVisibleEngines().map(engine => {
|
||||
return {
|
||||
name: engine.name,
|
||||
iconURI: engine.getIconURLBySize(16, 16),
|
||||
};
|
||||
}),
|
||||
currentEngine: currentEngineObj(),
|
||||
};
|
||||
}
|
||||
|
||||
function currentEngineObj(expectedCurrentEngine) {
|
||||
if (expectedCurrentEngine) {
|
||||
is(Services.search.currentEngine.name, expectedCurrentEngine.name,
|
||||
"Sanity check: expected current engine");
|
||||
}
|
||||
return {
|
||||
name: Services.search.currentEngine.name,
|
||||
logoURI: Services.search.currentEngine.getIconURLBySize(65, 26),
|
||||
logo2xURI: Services.search.currentEngine.getIconURLBySize(130, 52),
|
||||
};
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/* 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 TEST_MSG = "ContentSearchTest";
|
||||
const SERVICE_EVENT_TYPE = "ContentSearchService";
|
||||
const CLIENT_EVENT_TYPE = "ContentSearchClient";
|
||||
|
||||
// Forward events from the in-content service to the test.
|
||||
content.addEventListener(SERVICE_EVENT_TYPE, event => {
|
||||
sendAsyncMessage(TEST_MSG, event.detail);
|
||||
});
|
||||
|
||||
// Forward messages from the test to the in-content service.
|
||||
addMessageListener(TEST_MSG, msg => {
|
||||
content.dispatchEvent(
|
||||
new content.CustomEvent(CLIENT_EVENT_TYPE, {
|
||||
detail: msg.data,
|
||||
})
|
||||
);
|
||||
});
|
|
@ -199,6 +199,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/command-pick@2x.png (../shared/devtools/images/command-pick@2x.png)
|
||||
skin/classic/browser/devtools/command-console.png (../shared/devtools/images/command-console.png)
|
||||
skin/classic/browser/devtools/command-console@2x.png (../shared/devtools/images/command-console@2x.png)
|
||||
skin/classic/browser/devtools/command-eyedropper.png (../shared/devtools/images/command-eyedropper.png)
|
||||
skin/classic/browser/devtools/command-eyedropper@2x.png (../shared/devtools/images/command-eyedropper@2x.png)
|
||||
skin/classic/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
|
||||
* skin/classic/browser/devtools/ruleview.css (../shared/devtools/ruleview.css)
|
||||
* skin/classic/browser/devtools/webconsole.css (devtools/webconsole.css)
|
||||
|
@ -297,7 +299,6 @@ browser.jar:
|
|||
skin/classic/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
skin/classic/browser/devtools/app-manager/default-app-icon.png (../shared/devtools/app-manager/images/default-app-icon.png)
|
||||
skin/classic/browser/devtools/eyedropper-black.png (../shared/devtools/images/eyedropper-black.png)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/browser/sync-16.png
|
||||
skin/classic/browser/sync-32.png
|
||||
|
|
|
@ -320,6 +320,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/command-pick@2x.png (../shared/devtools/images/command-pick@2x.png)
|
||||
skin/classic/browser/devtools/command-console.png (../shared/devtools/images/command-console.png)
|
||||
skin/classic/browser/devtools/command-console@2x.png (../shared/devtools/images/command-console@2x.png)
|
||||
skin/classic/browser/devtools/command-eyedropper.png (../shared/devtools/images/command-eyedropper.png)
|
||||
skin/classic/browser/devtools/command-eyedropper@2x.png (../shared/devtools/images/command-eyedropper@2x.png)
|
||||
skin/classic/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
|
||||
* skin/classic/browser/devtools/ruleview.css (../shared/devtools/ruleview.css)
|
||||
skin/classic/browser/devtools/commandline.css (devtools/commandline.css)
|
||||
|
@ -418,7 +420,6 @@ browser.jar:
|
|||
skin/classic/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
skin/classic/browser/devtools/app-manager/default-app-icon.png (../shared/devtools/app-manager/images/default-app-icon.png)
|
||||
skin/classic/browser/devtools/eyedropper-black.png (../shared/devtools/images/eyedropper-black.png)
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/browser/sync-16.png
|
||||
|
|
|
@ -6,11 +6,4 @@
|
|||
<feFuncB type="table" tableValues=".1 0"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
<filter id="colorpicker-invert" x="0%" y="0%" width="100%" height="100%" >
|
||||
<feComponentTransfer>
|
||||
<feFuncR type="table" tableValues=".6 0"/>
|
||||
<feFuncG type="table" tableValues=".6 0"/>
|
||||
<feFuncB type="table" tableValues=".6 0"/>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 596 B После Ширина: | Высота: | Размер: 321 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.0 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.0 KiB |
Двоичные данные
browser/themes/shared/devtools/images/eyedropper-black.png
Двоичные данные
browser/themes/shared/devtools/images/eyedropper-black.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -580,6 +580,9 @@
|
|||
background-image: url("chrome://browser/skin/devtools/command-console.png");
|
||||
}
|
||||
|
||||
#command-button-eyedropper > image {
|
||||
background-image: url("chrome://browser/skin/devtools/command-eyedropper.png");
|
||||
}
|
||||
|
||||
@media (min-resolution: 2dppx) {
|
||||
#command-button-paintflashing > image {
|
||||
|
@ -605,6 +608,10 @@
|
|||
#command-button-splitconsole > image {
|
||||
background-image: url("chrome://browser/skin/devtools/command-console@2x.png");
|
||||
}
|
||||
|
||||
#command-button-eyedropper > image {
|
||||
background-image: url("chrome://browser/skin/devtools/command-eyedropper@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
|
|
|
@ -239,6 +239,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/command-pick@2x.png (../shared/devtools/images/command-pick@2x.png)
|
||||
skin/classic/browser/devtools/command-console.png (../shared/devtools/images/command-console.png)
|
||||
skin/classic/browser/devtools/command-console@2x.png (../shared/devtools/images/command-console@2x.png)
|
||||
skin/classic/browser/devtools/command-eyedropper.png (../shared/devtools/images/command-eyedropper.png)
|
||||
skin/classic/browser/devtools/command-eyedropper@2x.png (../shared/devtools/images/command-eyedropper@2x.png)
|
||||
skin/classic/browser/devtools/markup-view.css (../shared/devtools/markup-view.css)
|
||||
skin/classic/browser/devtools/editor-error.png (devtools/editor-error.png)
|
||||
skin/classic/browser/devtools/editor-breakpoint.png (devtools/editor-breakpoint.png)
|
||||
|
@ -333,7 +335,6 @@ browser.jar:
|
|||
skin/classic/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
skin/classic/browser/devtools/app-manager/default-app-icon.png (../shared/devtools/app-manager/images/default-app-icon.png)
|
||||
skin/classic/browser/devtools/eyedropper-black.png (../shared/devtools/images/eyedropper-black.png)
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/browser/sync-16.png
|
||||
|
@ -599,6 +600,8 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/command-pick@2x.png (../shared/devtools/images/command-pick@2x.png)
|
||||
skin/classic/aero/browser/devtools/command-console.png (../shared/devtools/images/command-console.png)
|
||||
skin/classic/aero/browser/devtools/command-console@2x.png (../shared/devtools/images/command-console@2x.png)
|
||||
skin/classic/aero/browser/devtools/command-eyedropper.png (../shared/devtools/images/command-eyedropper.png)
|
||||
skin/classic/aero/browser/devtools/command-eyedropper@2x.png (../shared/devtools/images/command-eyedropper@2x.png)
|
||||
skin/classic/aero/browser/devtools/alerticon-warning.png (devtools/alerticon-warning.png)
|
||||
* skin/classic/aero/browser/devtools/ruleview.css (../shared/devtools/ruleview.css)
|
||||
skin/classic/aero/browser/devtools/commandline.css (devtools/commandline.css)
|
||||
|
@ -695,8 +698,6 @@ browser.jar:
|
|||
skin/classic/aero/browser/devtools/app-manager/rocket.svg (../shared/devtools/app-manager/images/rocket.svg)
|
||||
skin/classic/aero/browser/devtools/app-manager/noise.png (../shared/devtools/app-manager/images/noise.png)
|
||||
skin/classic/aero/browser/devtools/app-manager/default-app-icon.png (../shared/devtools/app-manager/images/default-app-icon.png)
|
||||
skin/classic/aero/browser/devtools/eyedropper-black.png (../shared/devtools/images/eyedropper-black.png)
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/aero/browser/sync-16.png
|
||||
skin/classic/aero/browser/sync-32.png
|
||||
|
|
|
@ -109,12 +109,12 @@ template<class T> class nsReadingIterator;
|
|||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
class EventListenerManager;
|
||||
class Selection;
|
||||
|
||||
namespace dom {
|
||||
class DocumentFragment;
|
||||
class Element;
|
||||
class EventTarget;
|
||||
class Selection;
|
||||
} // namespace dom
|
||||
|
||||
namespace layers {
|
||||
|
@ -2086,7 +2086,7 @@ public:
|
|||
* @param aOutStartOffset Output start offset
|
||||
* @param aOutEndOffset Output end offset
|
||||
*/
|
||||
static void GetSelectionInTextControl(mozilla::Selection* aSelection,
|
||||
static void GetSelectionInTextControl(mozilla::dom::Selection* aSelection,
|
||||
Element* aRoot,
|
||||
int32_t& aOutStartOffset,
|
||||
int32_t& aOutEndOffset);
|
||||
|
|
|
@ -331,7 +331,7 @@ interface nsIXMLHttpRequest : nsISupports
|
|||
readonly attribute boolean mozSystem;
|
||||
};
|
||||
|
||||
[scriptable, uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
|
||||
[uuid(840d0d00-e83e-4a29-b3c7-67e96e90a499)]
|
||||
interface nsIXHRSendable : nsISupports {
|
||||
void getSendInfo(out nsIInputStream body,
|
||||
out uint64_t contentLength,
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "mozilla/Likely.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsAttrName.h"
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/EventDispatcher.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsITransferable.h" // for kUnicodeMime
|
||||
#include "nsContentUtils.h"
|
||||
|
|
|
@ -4,12 +4,6 @@
|
|||
# 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/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsICanvasGLPrivate.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'content_canvas'
|
||||
|
||||
EXPORTS += [
|
||||
'nsICanvasRenderingContextInternal.h',
|
||||
]
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
/* These are private interface that's used to identify
|
||||
* specific concrete classes so we know what we can cast.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(eba2aa03-ae19-46e2-bad7-6b966037e22c)]
|
||||
interface nsICanvasGLBuffer : nsISupports
|
||||
{
|
||||
};
|
||||
|
||||
[scriptable, uuid(27310aab-1988-43e8-882e-6293c8c9df60)]
|
||||
interface nsICanvasGLTexture : nsISupports
|
||||
{
|
||||
};
|
|
@ -12,8 +12,7 @@
|
|||
* which implements the phonetic interface.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(BC6EA726-AB56-46b6-A21A-AA7B76D6818F)]
|
||||
|
||||
[uuid(BC6EA726-AB56-46b6-A21A-AA7B76D6818F)]
|
||||
interface nsIPhonetic : nsISupports
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsTextEditRules.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "mozilla/EventListenerManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
|
|
@ -234,7 +234,7 @@ public:
|
|||
{
|
||||
// Deprecated
|
||||
}
|
||||
mozilla::Selection* GetSelection(mozilla::ErrorResult& aRv);
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aRv);
|
||||
// The XPCOM CaptureEvents works fine for us.
|
||||
// The XPCOM ReleaseEvents works fine for us.
|
||||
// We're picking up GetLocation from Document
|
||||
|
|
|
@ -2485,8 +2485,6 @@ XULDocument::PrepareToWalk()
|
|||
// Block onload until we've finished building the complete
|
||||
// document content model.
|
||||
BlockOnload();
|
||||
|
||||
nsContentSink::NotifyDocElementCreated(this);
|
||||
}
|
||||
|
||||
// There'd better not be anything on the context stack at this
|
||||
|
|
|
@ -5,7 +5,6 @@ support-files =
|
|||
overlay2_bug335375.xul
|
||||
window_bug583948.xul
|
||||
window_bug757137.xul
|
||||
window_documentnotification.xul
|
||||
|
||||
[test_bug199692.xul]
|
||||
[test_bug311681.xul]
|
||||
|
@ -21,4 +20,3 @@ support-files =
|
|||
[test_bug583948.xul]
|
||||
[test_bug640158_overlay_persist.xul]
|
||||
[test_bug757137.xul]
|
||||
[test_documentnotification.xul]
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<div id="content" style="display: none"/>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var seenNotification = false;
|
||||
function notify(subject, topic, data) {
|
||||
seenNotification = true;
|
||||
is(topic, "document-element-inserted", "Should be the right notification");
|
||||
is(subject, otherWindow.document, "Should have been notified about the right window");
|
||||
ok(subject.documentElement, "documentElement should be defined");
|
||||
}
|
||||
|
||||
var obs = Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService)
|
||||
obs.addObserver(notify, "document-element-inserted", false);
|
||||
|
||||
var otherWindow = window.open("window_documentnotification.xul", "_new", "chrome");
|
||||
otherWindow.addEventListener("load", function() {
|
||||
ok(seenNotification, "Should have seen the document-element-inserted")
|
||||
obs.removeObserver(notify, "document-element-inserted");
|
||||
window.close();
|
||||
SimpleTest.waitForFocus(function() {
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</window>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<label value="window_documentnotification.xul"/>
|
||||
</window>
|
|
@ -10871,21 +10871,31 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
|
||||
// Step 5: If aReplace is false, indicating that we're doing a pushState
|
||||
// rather than a replaceState, notify bfcache that we've added a page to
|
||||
// the history so it can evict content viewers if appropriate.
|
||||
// the history so it can evict content viewers if appropriate. Otherwise
|
||||
// call ReplaceEntry so that we notify nsIHistoryListeners that an entry
|
||||
// was replaced.
|
||||
nsCOMPtr<nsISHistory> rootSH;
|
||||
GetRootSessionHistory(getter_AddRefs(rootSH));
|
||||
NS_ENSURE_TRUE(rootSH, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsISHistoryInternal> internalSH =
|
||||
do_QueryInterface(rootSH);
|
||||
NS_ENSURE_TRUE(internalSH, NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (!aReplace) {
|
||||
nsCOMPtr<nsISHistory> rootSH;
|
||||
GetRootSessionHistory(getter_AddRefs(rootSH));
|
||||
NS_ENSURE_TRUE(rootSH, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsISHistoryInternal> internalSH =
|
||||
do_QueryInterface(rootSH);
|
||||
NS_ENSURE_TRUE(internalSH, NS_ERROR_UNEXPECTED);
|
||||
|
||||
int32_t curIndex = -1;
|
||||
rv = rootSH->GetIndex(&curIndex);
|
||||
if (NS_SUCCEEDED(rv) && curIndex > -1) {
|
||||
internalSH->EvictOutOfRangeContentViewers(curIndex);
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsISHEntry> rootSHEntry = GetRootSHEntry(newSHEntry);
|
||||
|
||||
int32_t index = -1;
|
||||
rv = rootSH->GetIndexOfEntry(rootSHEntry, &index);
|
||||
if (NS_SUCCEEDED(rv) && index > -1) {
|
||||
internalSH->ReplaceEntry(index, rootSHEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6: If the document's URI changed, update document's URI and update
|
||||
|
|
|
@ -22,12 +22,12 @@ interface nsISimpleEnumerator;
|
|||
|
||||
%{C++
|
||||
#define NS_SHISTORY_CID \
|
||||
{0x7294fe9c, 0x14d8, 0x11d5, {0x98, 0x82, 0x00, 0xC0, 0x4f, 0xa0, 0x2f, 0x40}}
|
||||
{0x7b807041, 0xe60a, 0x4384, {0x93, 0x5f, 0xaf, 0x30, 0x61, 0xd8, 0xb8, 0x15}}
|
||||
|
||||
#define NS_SHISTORY_CONTRACTID "@mozilla.org/browser/shistory;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(b4440e2e-0fc2-11e3-971f-59e799890b3c)]
|
||||
[scriptable, uuid(7b807041-e60a-4384-935f-af3061d8b815)]
|
||||
interface nsISHistory: nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -147,4 +147,16 @@ interface nsISHistory: nsISupports
|
|||
readonly attribute nsISimpleEnumerator SHistoryEnumerator;
|
||||
|
||||
void reloadCurrentEntry();
|
||||
|
||||
/**
|
||||
* Called to obtain the index to a given history entry.
|
||||
*
|
||||
* @param aEntry The entry to obtain the index of.
|
||||
*
|
||||
* @return <code>NS_OK</code> index for the history entry
|
||||
* is obtained successfully.
|
||||
* <code>NS_ERROR_FAILURE</code> Error in obtaining
|
||||
* index for the given history entry.
|
||||
*/
|
||||
long getIndexOfEntry(in nsISHEntry aEntry);
|
||||
};
|
||||
|
|
|
@ -21,7 +21,7 @@ interface nsIURI;
|
|||
* A session history listener can be registered on a particular nsISHistory
|
||||
* instance via the nsISHistory::addSHistoryListener() method.
|
||||
*/
|
||||
[scriptable, uuid(3b07f591-e8e1-11d4-9882-00c04fa02f40)]
|
||||
[scriptable, uuid(125c0833-746a-400e-9b89-d2d18545c08a)]
|
||||
interface nsISHistoryListener : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -87,4 +87,14 @@ interface nsISHistoryListener : nsISupports
|
|||
* @return Whether the operation can proceed.
|
||||
*/
|
||||
boolean OnHistoryPurge(in long aNumEntries);
|
||||
|
||||
/**
|
||||
* Called when an entry is replaced in the session history. Entries are
|
||||
* replaced when navigating away from non-persistent history entries (such as
|
||||
* about pages) and when history.replaceState is called.
|
||||
*
|
||||
* @param aIndex The index in session history of the entry being
|
||||
* replaced
|
||||
*/
|
||||
void OnHistoryReplaceEntry(in long aIndex);
|
||||
};
|
||||
|
|
|
@ -415,8 +415,11 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist)
|
|||
if(currentTxn)
|
||||
currentTxn->GetPersist(¤tPersist);
|
||||
|
||||
int32_t currentIndex = mIndex;
|
||||
|
||||
if(!currentPersist)
|
||||
{
|
||||
NOTIFY_LISTENERS(OnHistoryReplaceEntry, (currentIndex));
|
||||
NS_ENSURE_SUCCESS(currentTxn->SetSHEntry(aSHEntry),NS_ERROR_FAILURE);
|
||||
currentTxn->SetPersist(aPersist);
|
||||
return NS_OK;
|
||||
|
@ -426,7 +429,6 @@ nsSHistory::AddEntry(nsISHEntry * aSHEntry, bool aPersist)
|
|||
NS_ENSURE_TRUE(txn, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
int32_t currentIndex = mIndex;
|
||||
aSHEntry->GetURI(getter_AddRefs(uri));
|
||||
NOTIFY_LISTENERS(OnHistoryNewEntry, (uri));
|
||||
|
||||
|
@ -555,6 +557,50 @@ nsSHistory::GetTransactionAtIndex(int32_t aIndex, nsISHTransaction ** aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Get the index of a given entry */
|
||||
NS_IMETHODIMP
|
||||
nsSHistory::GetIndexOfEntry(nsISHEntry* aSHEntry, int32_t* aResult) {
|
||||
NS_ENSURE_ARG(aSHEntry);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = -1;
|
||||
|
||||
if (mLength <= 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISHTransaction> currentTxn;
|
||||
int32_t cnt = 0;
|
||||
|
||||
nsresult rv = GetRootTransaction(getter_AddRefs(currentTxn));
|
||||
if (NS_FAILED(rv) || !currentTxn) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
nsCOMPtr<nsISHEntry> entry;
|
||||
rv = currentTxn->GetSHEntry(getter_AddRefs(entry));
|
||||
if (NS_FAILED(rv) || !entry) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (aSHEntry == entry) {
|
||||
*aResult = cnt;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = currentTxn->GetNext(getter_AddRefs(currentTxn));
|
||||
if (NS_FAILED(rv) || !currentTxn) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
cnt++;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
nsresult
|
||||
nsSHistory::PrintHistory()
|
||||
|
@ -734,6 +780,8 @@ nsSHistory::ReplaceEntry(int32_t aIndex, nsISHEntry * aReplaceEntry)
|
|||
|
||||
if(currentTxn)
|
||||
{
|
||||
NOTIFY_LISTENERS(OnHistoryReplaceEntry, (aIndex));
|
||||
|
||||
// Set the replacement entry in the transaction
|
||||
rv = currentTxn->SetSHEntry(aReplaceEntry);
|
||||
rv = currentTxn->SetPersist(true);
|
||||
|
|
|
@ -39,6 +39,8 @@ SHistoryListener.prototype = {
|
|||
return this.retval;
|
||||
},
|
||||
|
||||
OnHistoryReplaceEntry: function (aIndex) {},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@ function test() {
|
|||
OnHistoryGoForward: function () true,
|
||||
OnHistoryGotoIndex: function () true,
|
||||
OnHistoryPurge: function () true,
|
||||
OnHistoryReplaceEntry: function () true,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(194b55d9-39c0-45c6-b8ef-b8049f978ea5)]
|
||||
[uuid(194b55d9-39c0-45c6-b8ef-b8049f978ea5)]
|
||||
interface nsIAudioChannelAgentCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ interface nsIAudioChannelAgentCallback : nsISupports
|
|||
* 1. Changes to the playable status of this channel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(2b0222a5-8f7b-49d2-9ab8-cd01b744b23e)]
|
||||
[uuid(2b0222a5-8f7b-49d2-9ab8-cd01b744b23e)]
|
||||
interface nsIAudioChannelAgent : nsISupports
|
||||
{
|
||||
const long AUDIO_AGENT_CHANNEL_NORMAL = 0;
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
// DOM core includes
|
||||
#include "nsError.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsIDOMXPathNamespace.h"
|
||||
#include "nsIDOMXULButtonElement.h"
|
||||
#include "nsIDOMXULCheckboxElement.h"
|
||||
#include "nsIDOMXULPopupElement.h"
|
||||
|
@ -223,7 +222,6 @@ DOMCI_DATA_NO_CLASS(DOMPrototype)
|
|||
DOMCI_DATA_NO_CLASS(DOMConstructor)
|
||||
|
||||
DOMCI_DATA_NO_CLASS(UserDataHandler)
|
||||
DOMCI_DATA_NO_CLASS(XPathNamespace)
|
||||
DOMCI_DATA_NO_CLASS(XULControlElement)
|
||||
DOMCI_DATA_NO_CLASS(XULLabeledControlElement)
|
||||
DOMCI_DATA_NO_CLASS(XULButtonElement)
|
||||
|
@ -448,8 +446,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(UserDataHandler, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(XPathNamespace, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControlElement, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULLabeledControlElement, nsDOMGenericSH,
|
||||
|
@ -1121,10 +1117,6 @@ nsDOMClassInfo::Init()
|
|||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMUserDataHandler)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XPathNamespace, nsIDOMXPathNamespace)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXPathNamespace)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControlElement, nsIDOMXULControlElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULControlElement)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -3166,7 +3158,6 @@ const InterfaceShimEntry kInterfaceShimMap[] =
|
|||
{ "nsIDOMRange", "Range" },
|
||||
{ "nsIDOMSVGLength", "SVGLength" },
|
||||
{ "nsIDOMNodeFilter", "NodeFilter" },
|
||||
{ "nsIDOMXPathNamespace", "XPathNamespace" },
|
||||
{ "nsIDOMXPathResult", "XPathResult" } };
|
||||
|
||||
static nsresult
|
||||
|
|
|
@ -93,7 +93,6 @@ DOMCI_CLASS(CSSPageRule)
|
|||
DOMCI_CLASS(CSSFontFeatureValuesRule)
|
||||
|
||||
DOMCI_CLASS(UserDataHandler)
|
||||
DOMCI_CLASS(XPathNamespace)
|
||||
DOMCI_CLASS(XULControlElement)
|
||||
DOMCI_CLASS(XULLabeledControlElement)
|
||||
DOMCI_CLASS(XULButtonElement)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "nsIBaseWindow.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIPrincipal.h"
|
||||
|
|
|
@ -172,7 +172,7 @@
|
|||
|
||||
#include "nsIDragService.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "mozilla/dom/Selection.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
|
@ -1607,6 +1607,8 @@ nsGlobalWindow::FreeInnerObjects()
|
|||
mAudioContexts.Clear();
|
||||
|
||||
#ifdef MOZ_GAMEPAD
|
||||
DisableGamepadUpdates();
|
||||
mHasGamepad = false;
|
||||
mGamepads.Clear();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -104,7 +104,6 @@ class nsWindowSizes;
|
|||
|
||||
namespace mozilla {
|
||||
class DOMEventTargetHelper;
|
||||
class Selection;
|
||||
namespace dom {
|
||||
class BarProp;
|
||||
class Console;
|
||||
|
@ -114,6 +113,7 @@ class Gamepad;
|
|||
class MediaQueryList;
|
||||
class Navigator;
|
||||
class OwningExternalOrWindowProxy;
|
||||
class Selection;
|
||||
class SpeechSynthesis;
|
||||
class WakeLock;
|
||||
namespace indexedDB {
|
||||
|
@ -882,7 +882,7 @@ public:
|
|||
mozilla::ErrorResult& aError);
|
||||
nsIDOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||
nsIDOMStorage* GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::indexedDB::IDBFactory* GetIndexedDB(mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsICSSDeclaration>
|
||||
GetComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt,
|
||||
|
|
|
@ -974,7 +974,6 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'Selection': {
|
||||
'nativeType': 'mozilla::Selection',
|
||||
'resultNotAddRefed': [ 'anchorNode', 'focusNode', 'getRangeAt' ],
|
||||
},
|
||||
|
||||
|
|
|
@ -276,28 +276,6 @@ KeyboardEvent::InitKeyEvent(const nsAString& aType,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
KeyboardEvent::InitKeyboardEvent(const nsAString& aType,
|
||||
bool aCanBubble,
|
||||
bool aCancelable,
|
||||
nsIDOMWindow* aView,
|
||||
uint32_t aDetail,
|
||||
const nsAString& aKey,
|
||||
uint32_t aLocation,
|
||||
const nsAString& aModifiersList,
|
||||
bool aRepeat,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
aRv = UIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
|
||||
|
||||
WidgetKeyboardEvent* keyEvent = mEvent->AsKeyboardEvent();
|
||||
keyEvent->modifiers = UIEvent::ComputeModifierState(aModifiersList);
|
||||
keyEvent->location = aLocation;
|
||||
keyEvent->mIsRepeat = aRepeat;
|
||||
keyEvent->mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
|
||||
keyEvent->mKeyValue = aKey;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -69,13 +69,6 @@ public:
|
|||
aKeyCode, aCharCode);
|
||||
}
|
||||
|
||||
void InitKeyboardEvent(const nsAString& aType,
|
||||
bool aCanBubble, bool aCancelable,
|
||||
nsIDOMWindow* aView, uint32_t aDetail,
|
||||
const nsAString& aKey, uint32_t aLocation,
|
||||
const nsAString& aModifiersList, bool aRepeat,
|
||||
ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
// True, if the instance is created with Constructor().
|
||||
bool mInitializedByCtor;
|
||||
|
|
|
@ -20,126 +20,55 @@ SimpleTest.waitForFocus(runTests, window);
|
|||
function testInitializingUntrustedEvent()
|
||||
{
|
||||
const kTests = [
|
||||
// initKeyEvent
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyboardEvent",
|
||||
type: "keydown", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 0
|
||||
keyCode: 0x00, charCode: 0x00 },
|
||||
|
||||
{ createEventArg: "keyboardevent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyboardevent",
|
||||
type: "keyup", bubbles: false, cancelable: true, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x10, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 1
|
||||
keyCode: 0x10, charCode: 0x00 },
|
||||
|
||||
{ createEventArg: "Keyboardevent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "Keyboardevent",
|
||||
type: "keypess", bubbles: true, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x11, charCode: 0x30,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 2
|
||||
keyCode: 0x11, charCode: 0x30 },
|
||||
|
||||
{ createEventArg: "keyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyboardEvent",
|
||||
type: "boo", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
|
||||
keyCode: 0x30, charCode: 0x40,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 3
|
||||
keyCode: 0x30, charCode: 0x40 },
|
||||
|
||||
{ createEventArg: "KeyEvents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyEvents",
|
||||
type: "foo", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
|
||||
keyCode: 0x00, charCode: 0x50,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 4
|
||||
keyCode: 0x00, charCode: 0x50 },
|
||||
|
||||
{ createEventArg: "keyevents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyevents",
|
||||
type: "bar", bubbles: false, cancelable: true, view: window,
|
||||
ctrlKey: true, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x60,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 5
|
||||
keyCode: 0x00, charCode: 0x60 },
|
||||
|
||||
{ createEventArg: "Keyevents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "Keyevents",
|
||||
type: "keydown", bubbles: true, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: true,
|
||||
keyCode: 0x30, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 6
|
||||
keyCode: 0x30, charCode: 0x00 },
|
||||
|
||||
{ createEventArg: "keyEvents", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "keyEvents",
|
||||
type: "keyup", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: true, metaKey: false,
|
||||
keyCode: 0x10, charCode: 0x80,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 7
|
||||
keyCode: 0x10, charCode: 0x80 },
|
||||
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyboardEvent",
|
||||
type: "keypress", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: true, metaKey: true,
|
||||
keyCode: 0x10, charCode: 0x80,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 8
|
||||
keyCode: 0x10, charCode: 0x80 },
|
||||
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: false,
|
||||
{ createEventArg: "KeyboardEvent",
|
||||
type: "foo", bubbles: false, cancelable: false, view: window,
|
||||
ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
|
||||
keyCode: 0x10, charCode: 0x80,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 9
|
||||
|
||||
// initKeyboardEvent
|
||||
{ createEventArg: "KeyboardEvent", useInitKeyboardEvent: true,
|
||||
type: "keydown", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "", location: 0, modifiersList: "", repeat: false,
|
||||
}, // 10
|
||||
|
||||
{ createEventArg: "keyboardevent", useInitKeyboardEvent: true,
|
||||
type: "keyup", bubbles: false, cancelable: true, view: window,
|
||||
ctrlKey: true, altKey: false, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 2, key: "Unidentified", location: 1, modifiersList: "Control", repeat: false,
|
||||
}, // 11
|
||||
|
||||
{ createEventArg: "Keyboardevent", useInitKeyboardEvent: true,
|
||||
type: "keypess", bubbles: true, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "FooBar", location: 2, modifiersList: "Alt", repeat: true,
|
||||
}, // 12
|
||||
|
||||
{ createEventArg: "keyboardevent", useInitKeyboardEvent: true,
|
||||
type: "foo", bubbles: true, cancelable: true, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: false, metaKey: true,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "a", location: 0, modifiersList: "Meta", repeat: false,
|
||||
}, // 13
|
||||
|
||||
{ createEventArg: "Keyevents", useInitKeyboardEvent: true,
|
||||
type: "", bubbles: false, cancelable: false, view: null,
|
||||
ctrlKey: true, altKey: true, shiftKey: true, metaKey: true,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "3", location: 0, modifiersList: "Control Alt Meta Shift", repeat: true,
|
||||
}, // 14
|
||||
|
||||
{ createEventArg: "keyevents", useInitKeyboardEvent: true,
|
||||
type: "", bubbles: false, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: false, shiftKey: true, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "3", location: 6, modifiersList: "Shift", repeat: true,
|
||||
}, // 15
|
||||
|
||||
{ createEventArg: "keyevents", useInitKeyboardEvent: true,
|
||||
type: "", bubbles: false, cancelable: false, view: null,
|
||||
ctrlKey: false, altKey: true, shiftKey: false, metaKey: false,
|
||||
keyCode: 0x00, charCode: 0x00,
|
||||
detail: 0, key: "", location: 4, modifiersList: "Shift, Alt", repeat: false,
|
||||
}, // 16
|
||||
keyCode: 0x10, charCode: 0x80 },
|
||||
];
|
||||
|
||||
const kOtherModifierName = [
|
||||
|
@ -156,23 +85,17 @@ function testInitializingUntrustedEvent()
|
|||
var description = "testInitializingUntrustedEvent, Index: " + i + ", ";
|
||||
const kTest = kTests[i];
|
||||
var e = document.createEvent(kTest.createEventArg);
|
||||
if (kTest.useInitKeyboardEvent) {
|
||||
// IE has extra argument for |.locale|. Calling with it shouldn't cause error for compatibility with IE.
|
||||
e.initKeyboardEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view, kTest.detail,
|
||||
kTest.key, kTest.location, kTest.modifiersList, kTest.repeat, "locale");
|
||||
} else {
|
||||
e.initKeyEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
|
||||
kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
|
||||
kTest.keyCode, kTest.charCode);
|
||||
}
|
||||
e.initKeyEvent(kTest.type, kTest.bubbles, kTest.cancelable, kTest.view,
|
||||
kTest.ctrlKey, kTest.altKey, kTest.shiftKey, kTest.metaKey,
|
||||
kTest.keyCode, kTest.charCode);
|
||||
is(e.toString(), "[object KeyboardEvent]",
|
||||
description + 'class string should be "KeyboardEvent"');
|
||||
|
||||
for (var attr in kTest) {
|
||||
if (attr == "createEventArg" || attr == "useInitKeyboardEvent" || attr == "modifiersList") {
|
||||
if (attr == "createEventArg") {
|
||||
continue;
|
||||
}
|
||||
if (!kTest.useInitKeyboardEvent && attr == "keyCode") {
|
||||
if (attr == "keyCode") {
|
||||
// If this is keydown, keyup of keypress event, keycod must be correct.
|
||||
if (kTest.type == "keydown" || kTest.type == "keyup" || kTest.type == "keypress") {
|
||||
is(e[attr], kTest[attr], description + attr + " returns wrong value");
|
||||
|
@ -180,7 +103,7 @@ function testInitializingUntrustedEvent()
|
|||
} else {
|
||||
is(e[attr], 0, description + attr + " returns non-zero for invalid event");
|
||||
}
|
||||
} else if (!kTest.useInitKeyboardEvent && attr == "charCode") {
|
||||
} else if (attr == "charCode") {
|
||||
// If this is keydown or keyup event, charCode always 0.
|
||||
if (kTest.type == "keydown" || kTest.type == "keyup") {
|
||||
is(e[attr], 0, description + attr + " returns non-zero for keydown or keyup event");
|
||||
|
@ -199,6 +122,9 @@ function testInitializingUntrustedEvent()
|
|||
}
|
||||
is(e.isTrusted, false, description + "isTrusted returns wrong value");
|
||||
|
||||
// Currently, there is no way to initialize char and key attribute values.
|
||||
ok(e.key === "", description + "key must return empty string - got " + e.key);
|
||||
|
||||
// getModifierState() tests
|
||||
is(e.getModifierState("Shift"), kTest.shiftKey,
|
||||
description + "getModifierState(\"Shift\") returns wrong value");
|
||||
|
|
|
@ -37,8 +37,8 @@
|
|||
[ "Callback message", msg, "Error: hello" ],
|
||||
[ "Event error-object", errorEvent.error, thrown],
|
||||
[ "Callback error-object", error, thrown ],
|
||||
[ "Event column", errorEvent.colno, 0 ], // Sadly not correct right now
|
||||
[ "Callback column", column, 0 ]
|
||||
[ "Event column", errorEvent.colno, 6 ], // Sadly not correct right now
|
||||
[ "Callback column", column, 6 ]
|
||||
]);
|
||||
</script>
|
||||
<script>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
* collection of DOM window objects.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(a6cf906f-15b3-11d2-932e-00805f8add32)]
|
||||
[uuid(a6cf906f-15b3-11d2-932e-00805f8add32)]
|
||||
interface nsIDOMWindowCollection : nsISupports
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -8,7 +8,6 @@ XPIDL_SOURCES += [
|
|||
'nsIDOMNSXPathExpression.idl',
|
||||
'nsIDOMXPathEvaluator.idl',
|
||||
'nsIDOMXPathExpression.idl',
|
||||
'nsIDOMXPathNamespace.idl',
|
||||
'nsIDOMXPathNSResolver.idl',
|
||||
'nsIDOMXPathResult.idl',
|
||||
]
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
/**
|
||||
* Corresponds to http://www.w3.org/TR/2002/WD-DOM-Level-3-XPath-20020208
|
||||
*/
|
||||
|
||||
#include "nsIDOMNode.idl"
|
||||
|
||||
[scriptable, uuid(558c2ab9-513e-43c2-afea-4930024b15b3)]
|
||||
interface nsIDOMXPathNamespace : nsIDOMNode
|
||||
{
|
||||
// XPathNodeType
|
||||
const unsigned short XPATH_NAMESPACE_NODE = 13;
|
||||
|
||||
readonly attribute nsIDOMElement ownerElement;
|
||||
};
|
|
@ -747,6 +747,7 @@ TabChild::Observe(nsISupports *aSubject,
|
|||
|
||||
if (SameCOMIdentity(subject, doc)) {
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils());
|
||||
utils->SetIsFirstPaint(true);
|
||||
|
||||
mContentDocumentIsDisplayed = true;
|
||||
|
||||
|
@ -810,9 +811,6 @@ TabChild::OnLocationChange(nsIWebProgress* aWebProgress,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils(do_GetInterface(window));
|
||||
utils->SetIsFirstPaint(true);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> progressDoc;
|
||||
window->GetDocument(getter_AddRefs(progressDoc));
|
||||
if (!progressDoc) {
|
||||
|
|
|
@ -584,7 +584,6 @@ exports.browser = {
|
|||
XPathEvaluator : false,
|
||||
XPathException : false,
|
||||
XPathExpression : false,
|
||||
XPathNamespace : false,
|
||||
XPathNSResolver : false,
|
||||
XPathResult : false
|
||||
};
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче