Merge m-c to s-c.

This commit is contained in:
Richard Newman 2012-12-18 11:43:03 -08:00
commit 26db612ea2
809 changed files with 29311 additions and 10024 deletions

View File

@ -14,30 +14,30 @@ namespace a11y {
*/
enum AccType {
eNoType,
eHTMLBR,
eHTMLButton,
eHTMLCanvas,
eHTMLCaption,
eHTMLCheckbox,
eHTMLCombobox,
eHTMLFileInput,
eHTMLGroupbox,
eHTMLHR,
eHTMLImageMap,
eHTMLLabel,
eHTMLLi,
eHTMLSelectList,
eHTMLMedia,
eHTMLRadioButton,
eHTMLTable,
eHTMLTableCell,
eHTMLTableRow,
eHTMLTextField,
eHyperText,
eImage,
eOuterDoc,
eHTMLBRType,
eHTMLButtonType,
eHTMLCanvasType,
eHTMLCaptionType,
eHTMLCheckboxType,
eHTMLComboboxType,
eHTMLFileInputType,
eHTMLGroupboxType,
eHTMLHRType,
eHTMLImageMapType,
eHTMLLabelType,
eHTMLLiType,
eHTMLSelectListType,
eHTMLMediaType,
eHTMLRadioButtonType,
eHTMLTableType,
eHTMLTableCellType,
eHTMLTableRowType,
eHTMLTextFieldType,
eHyperTextType,
eImageType,
eOuterDocType,
ePlugin,
eTextLeaf
eTextLeafType
};
}
}

View File

@ -30,6 +30,7 @@
#include "nsIWebNavigation.h"
#include "nsServiceManagerUtils.h"
using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
@ -329,7 +330,7 @@ DocManager::AddListeners(nsIDocument* aDocument,
nsIDOMEventTarget *target = window->GetChromeEventHandler();
nsEventListenerManager* elm = target->GetListenerManager(true);
elm->AddEventListenerByType(this, NS_LITERAL_STRING("pagehide"),
NS_EVENT_FLAG_CAPTURE);
dom::TrustedEventsAtCapture());
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocCreate))
@ -338,7 +339,7 @@ DocManager::AddListeners(nsIDocument* aDocument,
if (aAddDOMContentLoadedListener) {
elm->AddEventListenerByType(this, NS_LITERAL_STRING("DOMContentLoaded"),
NS_EVENT_FLAG_CAPTURE);
dom::TrustedEventsAtCapture());
#ifdef A11Y_LOG
if (logging::IsEnabled(logging::eDocCreate))
logging::Text("added 'DOMContentLoaded' listener");

View File

@ -107,7 +107,7 @@ NotificationController::Shutdown()
void
NotificationController::QueueEvent(AccEvent* aEvent)
{
NS_ASSERTION(aEvent->mAccessible && aEvent->mAccessible->IsApplication() ||
NS_ASSERTION((aEvent->mAccessible && aEvent->mAccessible->IsApplication()) ||
aEvent->GetDocAccessible() == mDocument,
"Queued event belongs to another document!");
@ -317,8 +317,8 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
void
NotificationController::CoalesceEvents()
{
uint32_t numQueuedEvents = mEvents.Length();
int32_t tail = numQueuedEvents - 1;
NS_ASSERTION(mEvents.Length(), "There should be at least one pending event!");
uint32_t tail = mEvents.Length() - 1;
AccEvent* tailEvent = mEvents[tail];
switch(tailEvent->mEventRule) {
@ -394,8 +394,7 @@ NotificationController::CoalesceEvents()
case AccEvent::eCoalesceSelectionChange:
{
AccSelChangeEvent* tailSelChangeEvent = downcast_accEvent(tailEvent);
int32_t index = tail - 1;
for (; index >= 0; index--) {
for (uint32_t index = tail - 1; index < tail; index--) {
AccEvent* thisEvent = mEvents[index];
if (thisEvent->mEventRule == tailEvent->mEventRule) {
AccSelChangeEvent* thisSelChangeEvent =
@ -508,7 +507,7 @@ NotificationController::CoalesceReorderEvents(AccEvent* aTailEvent)
void
NotificationController::CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
AccSelChangeEvent* aThisEvent,
int32_t aThisIndex)
uint32_t aThisIndex)
{
aTailEvent->mPreceedingCount = aThisEvent->mPreceedingCount + 1;

View File

@ -214,7 +214,7 @@ private:
*/
void CoalesceSelChangeEvents(AccSelChangeEvent* aTailEvent,
AccSelChangeEvent* aThisEvent,
int32_t aThisIndex);
uint32_t aThisIndex);
/**
* Coalesce text change events caused by sibling hide events.

View File

@ -799,13 +799,13 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
// on accessible HTML table elements.
if ((roleMapEntry->accTypes & Accessible::eTableCellAccessible)) {
if (aContext->IsOfType(Accessible::eTableRowAccessible) &&
(frame->AccessibleType() != eHTMLTableCell ||
(frame->AccessibleType() != eHTMLTableCellType ||
aContext->GetContent() != content->GetParent())) {
newAcc = new ARIAGridCellAccessibleWrap(content, document);
}
} else if ((roleMapEntry->accTypes & Accessible::eTableAccessible) &&
frame->AccessibleType() != eHTMLTable) {
frame->AccessibleType() != eHTMLTableType) {
newAcc = new ARIAGridAccessibleWrap(content, document);
}
}
@ -822,20 +822,20 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
// If table has strong ARIA role then all table descendants shouldn't
// expose their native roles.
if (!roleMapEntry && newAcc) {
if (frame->AccessibleType() == eHTMLTableRow) {
if (frame->AccessibleType() == eHTMLTableRowType) {
nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
if (contextRoleMap &&
!(contextRoleMap->accTypes & Accessible::eTableAccessible))
roleMapEntry = &nsARIAMap::gEmptyRoleMap;
} else if (frame->AccessibleType() == eHTMLTableCell &&
} else if (frame->AccessibleType() == eHTMLTableCellType &&
aContext->ARIARoleMap() == &nsARIAMap::gEmptyRoleMap) {
roleMapEntry = &nsARIAMap::gEmptyRoleMap;
} else if (content->Tag() == nsGkAtoms::dt ||
content->Tag() == nsGkAtoms::li ||
content->Tag() == nsGkAtoms::dd ||
frame->AccessibleType() == eHTMLLi) {
frame->AccessibleType() == eHTMLLiType) {
nsRoleMapEntry* contextRoleMap = aContext->ARIARoleMap();
if (contextRoleMap &&
!(contextRoleMap->accTypes & Accessible::eListAccessible))
@ -1308,67 +1308,67 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
switch (aFrame->AccessibleType()) {
case eNoType:
return nullptr;
case eHTMLBR:
case eHTMLBRType:
newAcc = new HTMLBRAccessible(aContent, document);
break;
case eHTMLButton:
case eHTMLButtonType:
newAcc = new HTMLButtonAccessible(aContent, document);
break;
case eHTMLCanvas:
case eHTMLCanvasType:
newAcc = new HTMLCanvasAccessible(aContent, document);
break;
case eHTMLCaption:
case eHTMLCaptionType:
if (aContext->IsOfType(Accessible::eTableAccessible) &&
aContext->GetContent() == aContent->GetParent()) {
newAcc = new HTMLCaptionAccessible(aContent, document);
}
break;
case eHTMLCheckbox:
case eHTMLCheckboxType:
newAcc = new HTMLCheckboxAccessible(aContent, document);
break;
case eHTMLCombobox:
case eHTMLComboboxType:
newAcc = new HTMLComboboxAccessible(aContent, document);
break;
case eHTMLFileInput:
case eHTMLFileInputType:
newAcc = new HTMLFileInputAccessible(aContent, document);
break;
case eHTMLGroupbox:
case eHTMLGroupboxType:
newAcc = new HTMLGroupboxAccessible(aContent, document);
break;
case eHTMLHR:
case eHTMLHRType:
newAcc = new HTMLHRAccessible(aContent, document);
break;
case eHTMLImageMap:
case eHTMLImageMapType:
newAcc = new HTMLImageMapAccessible(aContent, document);
break;
case eHTMLLabel:
case eHTMLLabelType:
newAcc = new HTMLLabelAccessible(aContent, document);
break;
case eHTMLLi:
case eHTMLLiType:
if (aContext->IsOfType(Accessible::eListAccessible) &&
aContext->GetContent() == aContent->GetParent()) {
newAcc = new HTMLLIAccessible(aContent, document);
}
break;
case eHTMLSelectList:
case eHTMLSelectListType:
newAcc = new HTMLSelectListAccessible(aContent, document);
break;
case eHTMLMedia:
case eHTMLMediaType:
newAcc = new EnumRoleAccessible(aContent, document, roles::GROUPING);
break;
case eHTMLRadioButton:
case eHTMLRadioButtonType:
newAcc = new HTMLRadioButtonAccessible(aContent, document);
break;
case eHTMLTable:
case eHTMLTableType:
newAcc = new HTMLTableAccessibleWrap(aContent, document);
break;
case eHTMLTableCell:
case eHTMLTableCellType:
// Accessible HTML table cell must be a child of accessible HTML table row.
if (aContext->IsOfType(Accessible::eHTMLTableRowAccessible))
newAcc = new HTMLTableCellAccessibleWrap(aContent, document);
break;
case eHTMLTableRow: {
case eHTMLTableRowType: {
// Accessible HTML table row must be a child of tbody/tfoot/thead of
// accessible HTML table or must be a child of accessible of HTML table.
if (aContext->IsOfType(Accessible::eTableAccessible)) {
@ -1386,18 +1386,18 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
}
break;
}
case eHTMLTextField:
case eHTMLTextFieldType:
newAcc = new HTMLTextFieldAccessible(aContent, document);
break;
case eHyperText:
case eHyperTextType:
if (aContent->Tag() != nsGkAtoms::dt && aContent->Tag() != nsGkAtoms::dd)
newAcc = new HyperTextAccessibleWrap(aContent, document);
break;
case eImage:
case eImageType:
newAcc = new ImageAccessibleWrap(aContent, document);
break;
case eOuterDoc:
case eOuterDocType:
newAcc = new OuterDocAccessible(aContent, document);
break;
case ePlugin: {
@ -1405,7 +1405,7 @@ nsAccessibilityService::CreateAccessibleByFrameType(nsIFrame* aFrame,
newAcc = CreatePluginAccessible(objectFrame, aContent, aContext);
break;
}
case eTextLeaf:
case eTextLeafType:
newAcc = new TextLeafAccessibleWrap(aContent, document);
break;
}

View File

@ -3,6 +3,8 @@
* 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 "mozilla/DebugOnly.h"
#include "HTMLTableAccessible.h"
#include "Accessible-inl.h"

View File

@ -1562,12 +1562,10 @@ AccessibleWrap::FirePlatformEvent(AccEvent* aEvent)
{
uint32_t eventType = aEvent->GetEventType();
NS_ENSURE_TRUE(eventType > 0 &&
eventType < nsIAccessibleEvent::EVENT_LAST_ENTRY,
NS_ERROR_FAILURE);
MOZ_STATIC_ASSERT(sizeof(gWinEventMap)/sizeof(gWinEventMap[0]) == nsIAccessibleEvent::EVENT_LAST_ENTRY,
"MSAA event map skewed");
NS_ASSERTION(gWinEventMap[nsIAccessibleEvent::EVENT_LAST_ENTRY] == kEVENT_LAST_ENTRY,
"MSAA event map skewed");
NS_ENSURE_TRUE(eventType > 0 && eventType < ArrayLength(gWinEventMap), NS_ERROR_FAILURE);
uint32_t winEvent = gWinEventMap[eventType];
if (!winEvent)

View File

@ -9,7 +9,6 @@
#include "AccessibleEventId.h"
const uint32_t kEVENT_WIN_UNKNOWN = 0x00000000;
const uint32_t kEVENT_LAST_ENTRY = 0xffffffff;
static const uint32_t gWinEventMap[] = {
kEVENT_WIN_UNKNOWN, // nsIAccessibleEvent doesn't have 0 constant
@ -98,7 +97,6 @@ static const uint32_t gWinEventMap[] = {
IA2_EVENT_HYPERTEXT_CHANGED, // nsIAccessibleEvent::EVENT_HYPERTEXT_CHANGED
IA2_EVENT_HYPERTEXT_NLINKS_CHANGED, // nsIAccessibleEvent::EVENT_HYPERTEXT_NLINKS_CHANGED
IA2_EVENT_OBJECT_ATTRIBUTE_CHANGED, // nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED
kEVENT_WIN_UNKNOWN, // nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED
kEVENT_LAST_ENTRY // nsIAccessibleEvent::EVENT_LAST_ENTRY
kEVENT_WIN_UNKNOWN // nsIAccessibleEvent::EVENT_VIRTUALCURSOR_CHANGED
};

View File

@ -33,6 +33,26 @@ function editableTextTestRun()
*/
function editableTextTest(aID)
{
/**
* Schedule a test, the given function with its arguments will be executed
* when preceding test is complete.
*/
this.scheduleTest = function scheduleTest(aFunc)
{
// A data container acts like a dummy invoker, it's never invoked but
// it's used to generate real invoker when previous invoker was handled.
var dataContainer = {
func: aFunc,
funcArgs: Array.slice(arguments, 1)
};
this.mEventQueue.push(dataContainer);
if (!this.mEventQueueReady) {
this.unwrapNextTest();
this.mEventQueueReady = true;
}
}
/**
* setTextContents test.
*/
@ -51,7 +71,7 @@ function editableTextTest(aID)
var oldValue = getValue(aID);
var removeTripple = oldValue ? [0, oldValue.length, oldValue] : null;
this.scheduleTest(aID, removeTripple, insertTripple, setTextContentsInvoke,
this.generateTest(aID, removeTripple, insertTripple, setTextContentsInvoke,
getValueChecker(aID, aValue), testID);
}
@ -70,7 +90,7 @@ function editableTextTest(aID)
}
var resPos = (aResPos != undefined) ? aResPos : aPos;
this.scheduleTest(aID, null, [resPos, resPos + aStr.length, aStr],
this.generateTest(aID, null, [resPos, resPos + aStr.length, aStr],
insertTextInvoke, getValueChecker(aID, aResStr), testID);
}
@ -88,7 +108,7 @@ function editableTextTest(aID)
acc.copyText(aStartPos, aEndPos);
}
this.scheduleTest(aID, null, null, copyTextInvoke,
this.generateTest(aID, null, null, copyTextInvoke,
getClipboardChecker(aID, aClipboardStr), testID);
}
@ -108,7 +128,7 @@ function editableTextTest(aID)
acc.pasteText(aPos);
}
this.scheduleTest(aID, null, [aStartPos, aEndPos, getTextFromClipboard],
this.generateTest(aID, null, [aStartPos, aEndPos, getTextFromClipboard],
copyNPasteInvoke, getValueChecker(aID, aResStr), testID);
}
@ -129,7 +149,7 @@ function editableTextTest(aID)
var resStartPos = (aResStartPos != undefined) ? aResStartPos : aStartPos;
var resEndPos = (aResEndPos != undefined) ? aResEndPos : aEndPos;
this.scheduleTest(aID, [resStartPos, resEndPos, getTextFromClipboard], null,
this.generateTest(aID, [resStartPos, resEndPos, getTextFromClipboard], null,
cutTextInvoke, getValueChecker(aID, aResStr), testID);
}
@ -149,7 +169,7 @@ function editableTextTest(aID)
acc.pasteText(aPos);
}
this.scheduleTest(aID, [aStartPos, aEndPos, getTextFromClipboard],
this.generateTest(aID, [aStartPos, aEndPos, getTextFromClipboard],
[aPos, -1, getTextFromClipboard],
cutNPasteTextInvoke, getValueChecker(aID, aResStr),
testID);
@ -168,7 +188,7 @@ function editableTextTest(aID)
acc.pasteText(aPos);
}
this.scheduleTest(aID, null, [aPos, -1, getTextFromClipboard],
this.generateTest(aID, null, [aPos, -1, getTextFromClipboard],
pasteTextInvoke, getValueChecker(aID, aResStr), testID);
}
@ -177,35 +197,20 @@ function editableTextTest(aID)
*/
this.deleteText = function deleteText(aStartPos, aEndPos, aResStr)
{
function getRemovedText() { return invoker.removedText; }
var testID = "deleteText from " + aStartPos + " to " + aEndPos +
" for " + prettyName(aID);
var invoker = {
eventSeq: [
new textChangeChecker(aID, aStartPos, aEndPos, getRemovedText, false)
],
var oldValue = getValue(aID).substring(aStartPos, aEndPos);
var removeTripple = oldValue ? [aStartPos, aEndPos, oldValue] : null;
invoke: function invoke()
{
var acc = getAccessible(aID,
[nsIAccessibleText, nsIAccessibleEditableText]);
function deleteTextInvoke()
{
var acc = getAccessible(aID, [nsIAccessibleEditableText]);
acc.deleteText(aStartPos, aEndPos);
}
this.removedText = acc.getText(aStartPos, aEndPos);
acc.deleteText(aStartPos, aEndPos);
},
finalCheck: function finalCheck()
{
getValueChecker(aID, aResStr).check();
},
getID: function getID()
{
return "deleteText from " + aStartPos + " to " + aEndPos + " for " +
prettyName(aID);
}
};
this.mEventQueue.push(invoker);
this.generateTest(aID, removeTripple, null, deleteTextInvoke,
getValueChecker(aID, aResStr), testID);
}
//////////////////////////////////////////////////////////////////////////////
@ -265,16 +270,31 @@ function editableTextTest(aID)
}
/**
* Create an invoker for the test and push it into event queue.
* Process next scheduled test.
*/
this.scheduleTest = function scheduleTest(aID, aRemoveTriple, aInsertTriple,
this.unwrapNextTest = function unwrapNextTest()
{
var data = this.mEventQueue.mInvokers[this.mEventQueue.mIndex + 1];
if (data)
data.func.apply(this, data.funcArgs);
}
/**
* Used to generate an invoker object for the sheduled test.
*/
this.generateTest = function generateTest(aID, aRemoveTriple, aInsertTriple,
aInvokeFunc, aChecker, aInvokerID)
{
var et = this;
var invoker = {
eventSeq: [],
invoke: aInvokeFunc,
finalCheck: function finalCheck() { aChecker.check(); },
finalCheck: function finalCheck()
{
aChecker.check();
et.unwrapNextTest(); // replace dummy invoker on real invoker object.
},
getID: function getID() { return aInvokerID; }
};
@ -292,7 +312,7 @@ function editableTextTest(aID)
invoker.eventSeq.push(checker);
}
this.mEventQueue.push(invoker);
this.mEventQueue.mInvokers[this.mEventQueue.mIndex + 1] = invoker;
}
/**
@ -318,5 +338,6 @@ function editableTextTest(aID)
}
this.mEventQueue = new eventQueue();
this.mEventQueueReady = false;
}

View File

@ -25,16 +25,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=452161
//////////////////////////////////////////////////////////////////////////
// setTextContents
et.setTextContents("hello");
et.setTextContents("olleh", aTrailChar); // due to some reason this reports '\n' in the end
et.setTextContents("");
et.scheduleTest(et.setTextContents, "hello");
et.scheduleTest(et.setTextContents, "olleh", aTrailChar); // due to some reason this reports '\n' in the end
et.scheduleTest(et.setTextContents, "");
//////////////////////////////////////////////////////////////////////////
// insertText
et.insertText("hello", 0, "hello");
et.insertText("ma ", 0, "ma hello");
et.insertText("ma", 2, "mama hello");
et.insertText(" hello", 10, "mama hello hello");
et.scheduleTest(et.insertText, "hello", 0, "hello");
et.scheduleTest(et.insertText, "ma ", 0, "ma hello");
et.scheduleTest(et.insertText, "ma", 2, "mama hello");
et.scheduleTest(et.insertText, " hello", 10, "mama hello hello");
// XXX: bug 452584

View File

@ -22,14 +22,14 @@
// 'ee' insertion/removal at 1 or 2 offset of 'hello'/'heeello' string
// reports 'ee' text was inserted/removed at 2 offset.
et.insertText("ee", 1, "heeello", 2);
et.copyText(1, 3, "ee");
et.cutText(1, 3, "hello", 2, 4);
et.insertText("ee", 2, "heeello", 2);
et.cutText(2, 4, "hello", 2, 4);
et.scheduleTest(et.insertText, "ee", 1, "heeello", 2);
et.scheduleTest(et.copyText, 1, 3, "ee");
et.scheduleTest(et.cutText, 1, 3, "hello", 2, 4);
et.scheduleTest(et.insertText, "ee", 2, "heeello", 2);
et.scheduleTest(et.cutText, 2, 4, "hello", 2, 4);
et.deleteText(1, 3, "hlo");
et.pasteText(1, "heelo");
et.scheduleTest(et.deleteText, 1, 3, "hlo");
et.scheduleTest(et.pasteText, 1, "heelo");
var testRun = new editableTextTestRun();
testRun.add(et);

View File

@ -174,7 +174,8 @@ pref("content.sink.perf_parse_time", 50000000);
// Maximum scripts runtime before showing an alert
pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome
pref("dom.max_script_run_time", 20);
// Bug 817230 - disable the dialog until we implement its checkbox properly
pref("dom.max_script_run_time", 0);
// plugins
pref("plugin.disable", true);
@ -481,6 +482,14 @@ pref("app.update.interval", 86400); // 1 day
// Don't throttle background updates.
pref("app.update.download.backgroundInterval", 0);
// Retry update socket connections every 30 seconds in the cases of certain kinds of errors
pref("app.update.socket.retryTimeout", 30000);
// Max of 20 consecutive retries (total 10 minutes) before giving up and marking
// the update download as failed.
// Note: Offline errors will always retry when the network comes online.
pref("app.update.socket.maxErrors", 20);
// Enable update logging for now, to diagnose growing pains in the
// field.
pref("app.update.log", true);

View File

@ -22,6 +22,9 @@ const Cu = Components.utils;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
// Preloading the CSP jsm in this process early on.
Cu.import("resource://gre/modules/CSPUtils.jsm");
function debug(msg) {
log(msg);
}

View File

@ -132,21 +132,6 @@
<menupopup>
</menupopup>
</menu>
<menu label="&charsetMenuUnicode.label;"
#ifndef OMIT_ACCESSKEYS
accesskey="&charsetMenuUnicode.accesskey;"
#endif
datasources="rdf:charset-menu" ref="NC:BrowserUnicodeCharsetMenuRoot">
<template>
<rule>
<menupopup>
<menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
</menupopup>
</rule>
</template>
<menupopup>
</menupopup>
</menu>
<menuseparator />
</menupopup>
</menu>

View File

@ -3,57 +3,10 @@
# 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 PLUGIN_SCRIPTED_STATE_NONE = 0;
const PLUGIN_SCRIPTED_STATE_FIRED = 1;
const PLUGIN_SCRIPTED_STATE_DONE = 2;
function getPluginInfo(pluginElement)
{
var tagMimetype;
var pluginsPage;
var pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
if (pluginElement instanceof HTMLAppletElement) {
tagMimetype = "application/x-java-vm";
} else {
if (pluginElement instanceof HTMLObjectElement) {
pluginsPage = pluginElement.getAttribute("codebase");
} else {
pluginsPage = pluginElement.getAttribute("pluginspage");
}
// only attempt if a pluginsPage is defined.
if (pluginsPage) {
var doc = pluginElement.ownerDocument;
var docShell = findChildShell(doc, gBrowser.docShell, null);
try {
pluginsPage = makeURI(pluginsPage, doc.characterSet, docShell.currentURI).spec;
} catch (ex) {
pluginsPage = "";
}
}
tagMimetype = pluginElement.QueryInterface(Components.interfaces.nsIObjectLoadingContent)
.actualType;
if (tagMimetype == "") {
tagMimetype = pluginElement.type;
}
}
if (tagMimetype) {
let navMimeType = navigator.mimeTypes.namedItem(tagMimetype);
if (navMimeType && navMimeType.enabledPlugin) {
pluginName = navMimeType.enabledPlugin.name;
pluginName = gPluginHandler.makeNicePluginName(pluginName);
}
}
return { mimetype: tagMimetype,
pluginsPage: pluginsPage,
pluginName: pluginName };
}
var gPluginHandler = {
PLUGIN_SCRIPTED_STATE_NONE: 0,
PLUGIN_SCRIPTED_STATE_FIRED: 1,
PLUGIN_SCRIPTED_STATE_DONE: 2,
#ifdef MOZ_CRASHREPORTER
get CrashSubmit() {
@ -63,6 +16,51 @@ var gPluginHandler = {
},
#endif
_getPluginInfo: function (pluginElement) {
let tagMimetype;
let pluginsPage;
let pluginName = gNavigatorBundle.getString("pluginInfo.unknownPlugin");
if (pluginElement instanceof HTMLAppletElement) {
tagMimetype = "application/x-java-vm";
} else {
if (pluginElement instanceof HTMLObjectElement) {
pluginsPage = pluginElement.getAttribute("codebase");
} else {
pluginsPage = pluginElement.getAttribute("pluginspage");
}
// only attempt if a pluginsPage is defined.
if (pluginsPage) {
let doc = pluginElement.ownerDocument;
let docShell = findChildShell(doc, gBrowser.docShell, null);
try {
pluginsPage = makeURI(pluginsPage, doc.characterSet, docShell.currentURI).spec;
} catch (ex) {
pluginsPage = "";
}
}
tagMimetype = pluginElement.QueryInterface(Ci.nsIObjectLoadingContent)
.actualType;
if (tagMimetype == "") {
tagMimetype = pluginElement.type;
}
}
if (tagMimetype) {
let navMimeType = navigator.mimeTypes.namedItem(tagMimetype);
if (navMimeType && navMimeType.enabledPlugin) {
pluginName = navMimeType.enabledPlugin.name;
pluginName = gPluginHandler.makeNicePluginName(pluginName);
}
}
return { mimetype: tagMimetype,
pluginsPage: pluginsPage,
pluginName: pluginName };
},
// Map the plugin's name to a filtered version more suitable for user UI.
makeNicePluginName : function (aName) {
if (aName == "Shockwave Flash")
@ -211,7 +209,7 @@ var gPluginHandler = {
case "PluginClickToPlay":
self._handleClickToPlayEvent(plugin);
let overlay = doc.getAnonymousElementByAttribute(plugin, "class", "mainBox");
let pluginName = getPluginInfo(plugin).pluginName;
let pluginName = self._getPluginInfo(plugin).pluginName;
let messageString = gNavigatorBundle.getFormattedString("PluginClickToPlay", [pluginName]);
let overlayText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgClickToPlay");
overlayText.textContent = messageString;
@ -234,8 +232,8 @@ var gPluginHandler = {
case "PluginScripted":
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
if (browser._pluginScriptedState == PLUGIN_SCRIPTED_STATE_NONE) {
browser._pluginScriptedState = PLUGIN_SCRIPTED_STATE_FIRED;
if (browser._pluginScriptedState == this.PLUGIN_SCRIPTED_STATE_NONE) {
browser._pluginScriptedState = this.PLUGIN_SCRIPTED_STATE_FIRED;
setTimeout(function() {
gPluginHandler.handlePluginScripted(this);
}.bind(browser), 500);
@ -285,7 +283,7 @@ var gPluginHandler = {
this._notificationDisplayedOnce = true;
}
aBrowser._pluginScriptedState = PLUGIN_SCRIPTED_STATE_DONE;
aBrowser._pluginScriptedState = this.PLUGIN_SCRIPTED_STATE_DONE;
},
isKnownPlugin: function PH_isKnownPlugin(objLoadingContent) {
@ -338,7 +336,6 @@ var gPluginHandler = {
let browser = gBrowser.getBrowserForDocument(aContentWindow.document);
let notification = PopupNotifications.getNotification("click-to-play-plugins", browser);
if (notification) {
browser._clickToPlayDoorhangerShown = false;
notification.remove();
}
if (pluginNeedsActivation) {
@ -376,7 +373,7 @@ var gPluginHandler = {
installSinglePlugin: function (plugin) {
var missingPlugins = new Map();
var pluginInfo = getPluginInfo(plugin);
var pluginInfo = this._getPluginInfo(plugin);
missingPlugins.set(pluginInfo.mimetype, pluginInfo);
openDialog("chrome://mozapps/content/plugins/pluginInstallerWizard.xul",
@ -454,8 +451,7 @@ var gPluginHandler = {
}, true);
}
if (!browser._clickToPlayDoorhangerShown)
gPluginHandler._showClickToPlayNotification(browser);
gPluginHandler._showClickToPlayNotification(browser);
},
_handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
@ -471,7 +467,7 @@ var gPluginHandler = {
// Force a style flush, so that we ensure our binding is attached.
aPlugin.clientTop;
}
let pluginInfo = getPluginInfo(aPlugin);
let pluginInfo = this._getPluginInfo(aPlugin);
let playPreviewUri = "data:application/x-moz-playpreview;," + pluginInfo.mimetype;
iframe.src = playPreviewUri;
@ -520,7 +516,7 @@ var gPluginHandler = {
for (let plugin of aDOMWindowUtils.plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
let pluginName = getPluginInfo(plugin).pluginName;
let pluginName = this._getPluginInfo(plugin).pluginName;
if (aName == pluginName) {
plugins.push(objLoadingContent);
}
@ -537,7 +533,7 @@ var gPluginHandler = {
for (let plugin of cwu.plugins) {
let objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
if (gPluginHandler.canActivatePlugin(objLoadingContent)) {
let pluginName = getPluginInfo(plugin).pluginName;
let pluginName = this._getPluginInfo(plugin).pluginName;
if (!pluginsDictionary.has(pluginName))
pluginsDictionary.set(pluginName, []);
pluginsDictionary.get(pluginName).push(objLoadingContent);
@ -603,9 +599,7 @@ var gPluginHandler = {
},
_showClickToPlayNotification: function PH_showClickToPlayNotification(aBrowser) {
aBrowser._clickToPlayDoorhangerShown = true;
let contentWindow = aBrowser.contentWindow;
let messageString = gNavigatorBundle.getString("activatePluginsMessage.message");
let mainAction = {
label: gNavigatorBundle.getString("activateAllPluginsMessage.label"),
@ -670,7 +664,7 @@ var gPluginHandler = {
if (!browser.missingPlugins)
browser.missingPlugins = new Map();
var pluginInfo = getPluginInfo(plugin);
var pluginInfo = this._getPluginInfo(plugin);
browser.missingPlugins.set(pluginInfo.mimetype, pluginInfo);
var notificationBox = gBrowser.getNotificationBox(browser);

View File

@ -2321,6 +2321,10 @@ function URLBarSetURI(aURI) {
if (value == null) {
let uri = aURI || gBrowser.currentURI;
// Strip off "wyciwyg://" and passwords for the location bar
try {
uri = Services.uriFixup.createExposableURI(uri);
} catch (e) {}
// Replace initial page URIs with an empty string
// only if there's no opener (bug 370555).
@ -3495,7 +3499,7 @@ function OpenBrowserWindow(options)
var extraFeatures = "";
#ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
if (typeof options == "object" && options.private) {
if (options && options.private) {
#else
if (gPrivateBrowsingUI.privateBrowsingEnabled) {
#endif
@ -3801,11 +3805,6 @@ var XULBrowserWindow = {
delete this.isImage;
return this.isImage = document.getElementById("isImage");
},
get _uriFixup () {
delete this._uriFixup;
return this._uriFixup = Cc["@mozilla.org/docshell/urifixup;1"]
.getService(Ci.nsIURIFixup);
},
init: function () {
this.throbberElement = document.getElementById("navigator-throbber");
@ -4099,12 +4098,7 @@ var XULBrowserWindow = {
}
if (gURLBar) {
// Strip off "wyciwyg://" and passwords for the location bar
let uri = aLocationURI;
try {
uri = this._uriFixup.createExposableURI(uri);
} catch (e) {}
URLBarSetURI(uri);
URLBarSetURI(aLocationURI);
// Update starring UI
PlacesStarButton.updateState();
@ -4524,9 +4518,8 @@ var TabsProgressListener = {
// or history.push/pop/replaceState.
if (aRequest) {
// Initialize the click-to-play state.
aBrowser._clickToPlayDoorhangerShown = false;
aBrowser._clickToPlayPluginsActivated = false;
aBrowser._pluginScriptedState = PLUGIN_SCRIPTED_STATE_NONE;
aBrowser._pluginScriptedState = gPluginHandler.PLUGIN_SCRIPTED_STATE_NONE;
}
FullZoom.onLocationChange(aLocationURI, false, aBrowser);
}

View File

@ -255,6 +255,7 @@ _BROWSER_FILES = \
plugin_bug749455.html \
plugin_bug797677.html \
plugin_bug818009.html \
plugin_bug820497.html \
plugin_hidden_to_visible.html \
plugin_two_types.html \
alltabslistener.html \
@ -283,12 +284,14 @@ _BROWSER_FILES = \
browser_bug812562.js \
browser_bug818009.js \
browser_bug818118.js \
browser_bug820497.js \
blockPluginVulnerableUpdatable.xml \
blockPluginVulnerableNoUpdate.xml \
blockNoPlugins.xml \
browser_utilityOverlay.js \
browser_bug676619.js \
download_page.html \
browser_URLBarSetURI.js \
$(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))

View File

@ -0,0 +1,82 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
function test() {
waitForExplicitFinish();
// avoid prompting about phishing
Services.prefs.setIntPref(phishyUserPassPref, 32);
registerCleanupFunction(function () {
Services.prefs.clearUserPref(phishyUserPassPref);
});
nextTest();
}
const phishyUserPassPref = "network.http.phishy-userpass-length";
function nextTest() {
let test = tests.shift();
if (test) {
test(function () {
executeSoon(nextTest);
});
} else {
executeSoon(finish);
}
}
let tests = [
function revert(next) {
loadTabInWindow(window, function (tab) {
gURLBar.handleRevert();
is(gURLBar.value, "example.com", "URL bar had user/pass stripped after reverting");
gBrowser.removeTab(tab);
next();
});
},
function customize(next) {
whenNewWindowLoaded(undefined, function (win) {
// Need to wait for delayedStartup for the customization part of the test,
// since that's where BrowserToolboxCustomizeDone is set.
whenDelayedStartupFinished(win, function () {
loadTabInWindow(win, function () {
openToolbarCustomizationUI(function () {
closeToolbarCustomizationUI(function () {
is(win.gURLBar.value, "example.com", "URL bar had user/pass stripped after customize");
win.close();
next();
}, win);
}, win);
});
});
});
},
function pageloaderror(next) {
loadTabInWindow(window, function (tab) {
// Load a new URL and then immediately stop it, to simulate a page load
// error.
tab.linkedBrowser.loadURI("http://test1.example.com");
tab.linkedBrowser.stop();
is(gURLBar.value, "example.com", "URL bar had user/pass stripped after load error");
gBrowser.removeTab(tab);
next();
});
}
];
function loadTabInWindow(win, callback) {
info("Loading tab");
let url = "http://user:pass@example.com/";
let tab = win.gBrowser.selectedTab = win.gBrowser.addTab(url);
tab.linkedBrowser.addEventListener("load", function listener() {
info("Tab loaded");
if (tab.linkedBrowser.currentURI.spec != url)
return;
tab.linkedBrowser.removeEventListener("load", listener, true);
is(win.gURLBar.value, "example.com", "URL bar had user/pass stripped initially");
callback(tab);
}, true);
}

View File

@ -3,45 +3,42 @@
*/
let Ci = Components.interfaces;
let testWindow = null;
function test() {
waitForExplicitFinish();
testWindow = OpenBrowserWindow();
testWindow.addEventListener("load", function(aEvent) {
testWindow.removeEventListener("load", arguments.callee, false);
ok(true, "Load listener called");
executeSoon(function() {
let selectedBrowser = testWindow.gBrowser.selectedBrowser;
whenNewWindowLoaded(undefined, function (win) {
whenDelayedStartupFinished(win, function () {
let selectedBrowser = win.gBrowser.selectedBrowser;
selectedBrowser.addEventListener("pageshow", function() {
selectedBrowser.removeEventListener("pageshow", arguments.callee, true);
ok(true, "pageshow listener called");
waitForFocus(onFocus, testWindow.contentWindow);
ok(true, "pageshow listener called: " + win.content.location);
waitForFocus(function () {
onFocus(win);
}, selectedBrowser.contentWindow);
}, true);
testWindow.content.location = "data:text/html,<h1 id='h1'>Select Me</h1>";
selectedBrowser.loadURI("data:text/html,<h1 id='h1'>Select Me</h1>");
});
}, false);
});
}
function selectText() {
let elt = testWindow.content.document.getElementById("h1");
let selection = testWindow.content.getSelection();
let range = testWindow.content.document.createRange();
function selectText(win) {
let elt = win.document.getElementById("h1");
let selection = win.getSelection();
let range = win.document.createRange();
range.setStart(elt, 0);
range.setEnd(elt, 1);
selection.removeAllRanges();
selection.addRange(range);
}
function onFocus() {
ok(!testWindow.gFindBarInitialized, "find bar is not yet initialized");
let findBar = testWindow.gFindBar;
selectText();
function onFocus(win) {
ok(!win.gFindBarInitialized, "find bar is not yet initialized");
let findBar = win.gFindBar;
selectText(win.content);
findBar.onFindCommand();
is(findBar._findField.value, "Select Me", "Findbar is initialized with selection");
findBar.close();
testWindow.close();
win.close();
finish();
}

View File

@ -0,0 +1,53 @@
/* 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/. */
var gTestBrowser = null;
var gNumPluginBindingsAttached = 0;
Components.utils.import("resource://gre/modules/Services.jsm");
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("plugins.click_to_play");
gTestBrowser.removeEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
gBrowser.removeCurrentTab();
window.focus();
});
Services.prefs.setBoolPref("plugins.click_to_play", true);
gBrowser.selectedTab = gBrowser.addTab();
gTestBrowser = gBrowser.selectedBrowser;
gTestBrowser.addEventListener("PluginBindingAttached", pluginBindingAttached, true, true);
var gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug820497.html";
}
function pluginBindingAttached() {
gNumPluginBindingsAttached++;
if (gNumPluginBindingsAttached == 1) {
var doc = gTestBrowser.contentDocument;
var testplugin = doc.getElementById("test");
ok(testplugin, "should have test plugin");
var secondtestplugin = doc.getElementById("secondtest");
ok(!secondtestplugin, "should not yet have second test plugin");
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have popup notification");
is(notification.options.centerActions.length, 1, "should be 1 type of plugin in the popup notification");
} else if (gNumPluginBindingsAttached == 2) {
var doc = gTestBrowser.contentDocument;
var testplugin = doc.getElementById("test");
ok(testplugin, "should have test plugin");
var secondtestplugin = doc.getElementById("secondtest");
ok(secondtestplugin, "should have second test plugin");
var notification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
ok(notification, "should have popup notification");
is(notification.options.centerActions.length, 2, "should be 2 types of plugin in the popup notification");
finish();
} else {
ok(false, "if we've gotten here, something is quite wrong");
}
}

View File

@ -99,7 +99,7 @@ function testExpectNoPopupPart1() {
}
function testExpectNoPopupPart2() {
var condition = function() gTestBrowser._pluginScriptedState == PLUGIN_SCRIPTED_STATE_DONE;
var condition = function() gTestBrowser._pluginScriptedState == gPluginHandler.PLUGIN_SCRIPTED_STATE_DONE;
waitForCondition(condition, testExpectNoPopupPart3, "waited too long for PluginScripted event handling (" + getCurrentTestLocation() + ")");
}

View File

@ -6,6 +6,7 @@ var gTestBrowser = null;
var gNextTest = null;
var gClickToPlayPluginActualEvents = 0;
var gClickToPlayPluginExpectedEvents = 5;
var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
Components.utils.import("resource://gre/modules/Services.jsm");
@ -420,7 +421,7 @@ function test12d() {
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
ok(!objLoadingContent.activated, "Test 12d, Second Test plugin (B) should not be activated");
Services.perms.removeAll();
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
prepareTest(test13a, gHttpTestRoot + "plugin_clickToPlayDeny.html");
}
@ -510,7 +511,7 @@ function test13e() {
var objLoadingContent = secondtestB.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 13e, Second Test plugin (B) should be activated");
Services.perms.removeAll();
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
Services.prefs.setBoolPref("plugins.click_to_play", false);
prepareTest(test14, gTestRoot + "plugin_test2.html");
}
@ -524,7 +525,6 @@ function test14() {
var plugin = getTestPlugin();
plugin.disabled = false;
plugin.blocklisted = false;
Services.perms.removeAll();
Services.prefs.setBoolPref("plugins.click_to_play", true);
prepareTest(test15, gTestRoot + "plugin_alternate_content.html");
}
@ -657,7 +657,7 @@ function test18c() {
var updateLink = doc.getAnonymousElementByAttribute(plugin, "class", "checkForUpdatesLink");
ok(updateLink.style.display != "block", "Test 18c, Plugin should not have an update link");
// check that click "Always allow" works with blocklisted plugins (for now)
// check that click "Always allow" works with blocklisted plugins
clickToPlayNotification.secondaryActions[0].callback();
var condition = function() objLoadingContent.activated;
waitForCondition(condition, test18d, "Test 18d, Waited too long for plugin to activate");
@ -682,7 +682,7 @@ function test18e() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 18e, Plugin should be activated");
Services.perms.removeAll();
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml",
function() {
resetBlocklist();
@ -1060,9 +1060,12 @@ function test24d() {
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
ok(objLoadingContent.activated, "Test 24d, plugin should be activated");
Services.perms.removeAll();
// this resets the vulnerable plugin permission
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
setAndUpdateBlocklist(gHttpTestRoot + "blockNoPlugins.xml",
function() {
// this resets the normal plugin permission
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
resetBlocklist();
prepareTest(test25a, gHttpTestRoot + "plugin_test.html");
});
@ -1120,7 +1123,8 @@ function test25c() {
var overlay = gTestBrowser.contentDocument.getAnonymousElementByAttribute(secondtest, "class", "mainBox");
ok(overlay.style.visibility == "hidden", "Test 25c, second test plugin should not have visible overlay");
Services.perms.removeAll();
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-test"));
Services.perms.remove("127.0.0.1:8888", gPluginHost.getPermissionStringForType("application/x-second-test"));
finishTest();
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"/></head>
<body onload="addSecondPlugin()">
<object id="test" type="application/x-test" width=200 height=200></object>
<script>
function addSecondPlugin() {
var object = document.createElement("object");
object.type = "application/x-second-test";
object.width = 200;
object.height = 200;
object.id = "secondtest";
document.body.appendChild(object);
}
</script>
</body>
</html>

View File

@ -20,7 +20,7 @@ _BROWSER_FILES = \
browser_social_mozSocial_API.js \
browser_social_isVisible.js \
browser_social_chatwindow.js \
browser_social_multiprovider.js \
$(filter disabled-temporarily--bug-820489, browser_social_multiprovider.js) \
social_panel.html \
social_share_image.png \
social_sidebar.html \

View File

@ -44,8 +44,37 @@ function runSocialTestWithProvider(manifest, callback) {
info("runSocialTestWithProvider: " + manifests.toSource());
let finishCount = 0;
function finishIfDone(callFinish) {
finishCount++;
if (finishCount == manifests.length)
finish();
}
function removeAddedProviders(cleanup) {
manifests.forEach(function (m) {
// If we're "cleaning up", don't call finish when done.
let callback = cleanup ? function () {} : finishIfDone;
// Similarly, if we're cleaning up, catch exceptions from removeProvider
let removeProvider = SocialService.removeProvider.bind(SocialService);
if (cleanup) {
removeProvider = function (origin, cb) {
try {
SocialService.removeProvider(origin, cb);
} catch (ex) {
// Ignore "provider doesn't exist" errors.
if (ex.message == "SocialService.removeProvider: no provider with this origin exists!")
return;
info("Failed to clean up provider " + origin + ": " + ex);
}
}
}
removeProvider(m.origin, callback);
});
}
let providersAdded = 0;
let firstProvider;
manifests.forEach(function (m) {
SocialService.addProvider(m, function(provider) {
provider.active = true;
@ -65,23 +94,15 @@ function runSocialTestWithProvider(manifest, callback) {
Social.provider = firstProvider;
Social.enabled = true;
registerCleanupFunction(function () {
function finishSocialTest(cleanup) {
// disable social before removing the providers to avoid providers
// being activated immediately before we get around to removing it.
Services.prefs.clearUserPref("social.enabled");
// if one test happens to fail, it is likely finishSocialTest will not
// be called, causing most future social tests to also fail as they
// attempt to add a provider which already exists - so work
// around that by also attempting to remove the test provider.
manifests.forEach(function (m) {
try {
SocialService.removeProvider(m.origin, finish);
} catch (ex) {}
});
});
function finishSocialTest() {
SocialService.removeProvider(provider.origin, finish);
removeAddedProviders(cleanup);
}
registerCleanupFunction(function () {
finishSocialTest(true);
});
callback(finishSocialTest);
}
});

View File

@ -54,7 +54,7 @@ richlistitem[type="download"]:not([selected]) button {
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromListMenuItem,
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */

View File

@ -46,6 +46,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon",
"resource:///modules/DownloadsCommon.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
"resource://gre/modules/NetUtil.jsm");
////////////////////////////////////////////////////////////////////////////////
//// DownloadsPanel
@ -335,7 +339,7 @@ const DownloadsPanel = {
return;
}
let uri = Services.io.newURI(url, null, null);
let uri = NetUtil.newURI(url);
saveURL(uri.spec, name || uri.spec, null, true, true,
undefined, document);
} catch (ex) {}
@ -1187,12 +1191,6 @@ function DownloadsViewItemController(aElement) {
}
DownloadsViewItemController.prototype = {
//////////////////////////////////////////////////////////////////////////////
//// Constants
get kPrefBdmAlertOnExeOpen() "browser.download.manager.alertOnEXEOpen",
get kPrefBdmScanWhenDone() "browser.download.manager.scanWhenDone",
//////////////////////////////////////////////////////////////////////////////
//// Command dispatching
@ -1244,87 +1242,18 @@ DownloadsViewItemController.prototype = {
commands: {
cmd_delete: function DVIC_cmd_delete()
{
this.dataItem.getDownload(function (aDownload) {
if (this.dataItem.inProgress) {
aDownload.cancel();
this._ensureLocalFileRemoved();
}
aDownload.remove();
}.bind(this));
this.dataItem.remove();
PlacesUtils.bhistory.removePage(NetUtil.newURI(this.dataItem.uri));
},
downloadsCmd_cancel: function DVIC_downloadsCmd_cancel()
{
if (this.dataItem.inProgress) {
this.dataItem.getDownload(function (aDownload) {
aDownload.cancel();
this._ensureLocalFileRemoved();
}.bind(this));
}
this.dataItem.cancel();
},
downloadsCmd_open: function DVIC_downloadsCmd_open()
{
// Confirm opening executable files if required.
let localFile = this.dataItem.localFile;
if (localFile.isExecutable()) {
let showAlert = true;
try {
showAlert = Services.prefs.getBoolPref(this.kPrefBdmAlertOnExeOpen);
} catch (ex) { }
// On Vista and above, we rely on native security prompting for
// downloaded content unless it's disabled.
if (DownloadsCommon.isWinVistaOrHigher) {
try {
if (Services.prefs.getBoolPref(this.kPrefBdmScanWhenDone)) {
showAlert = false;
}
} catch (ex) { }
}
if (showAlert) {
let name = this.dataItem.target;
let message =
DownloadsCommon.strings.fileExecutableSecurityWarning(name, name);
let title =
DownloadsCommon.strings.fileExecutableSecurityWarningTitle;
let dontAsk =
DownloadsCommon.strings.fileExecutableSecurityWarningDontAsk;
let checkbox = { value: false };
let open = Services.prompt.confirmCheck(window, title, message,
dontAsk, checkbox);
if (!open) {
return;
}
Services.prefs.setBoolPref(this.kPrefBdmAlertOnExeOpen,
!checkbox.value);
}
}
// Actually open the file.
this.dataItem.getDownload(function (aDownload) {
try {
let launched = false;
try {
let mimeInfo = aDownload.MIMEInfo;
if (mimeInfo.preferredAction == mimeInfo.useHelperApp) {
mimeInfo.launchWithFile(localFile);
launched = true;
}
} catch (ex) { }
if (!launched) {
localFile.launch();
}
} catch (ex) {
// If launch fails, try sending it through the system's external "file:"
// URL handler.
this._openExternal(localFile);
}
}.bind(this));
this.dataItem.openLocalFile();
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
// Otherwise, we'd have to wait for the file-type handler to execute
@ -1335,26 +1264,7 @@ DownloadsViewItemController.prototype = {
downloadsCmd_show: function DVIC_downloadsCmd_show()
{
let localFile = this.dataItem.localFile;
try {
// Show the directory containing the file and select the file.
localFile.reveal();
} catch (ex) {
// If reveal fails for some reason (e.g., it's not implemented on unix
// or the file doesn't exist), try using the parent if we have it.
let parent = localFile.parent.QueryInterface(Ci.nsILocalFile);
if (parent) {
try {
// Open the parent directory to show where the file should be.
parent.launch();
} catch (ex) {
// If launch also fails (probably because it's not implemented), let
// the OS handler try to open the parent.
this._openExternal(parent);
}
}
}
this.dataItem.showLocalFile();
// We explicitly close the panel here to give the user the feedback that
// their click has been received, and we're handling the action.
@ -1366,20 +1276,12 @@ DownloadsViewItemController.prototype = {
downloadsCmd_pauseResume: function DVIC_downloadsCmd_pauseResume()
{
this.dataItem.getDownload(function (aDownload) {
if (this.dataItem.paused) {
aDownload.resume();
} else {
aDownload.pause();
}
}.bind(this));
this.dataItem.togglePauseResume();
},
downloadsCmd_retry: function DVIC_downloadsCmd_retry()
{
this.dataItem.getDownload(function (aDownload) {
aDownload.retry();
});
this.dataItem.retry();
},
downloadsCmd_openReferrer: function DVIC_downloadsCmd_openReferrer()
@ -1418,31 +1320,6 @@ DownloadsViewItemController.prototype = {
// Invoke the command.
this.doCommand(defaultCommand);
}
},
/**
* Support function to open the specified nsIFile.
*/
_openExternal: function DVIC_openExternal(aFile)
{
let protocolSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Ci.nsIExternalProtocolService);
protocolSvc.loadUrl(makeFileURI(aFile));
},
/**
* Support function that deletes the local file for a download. This is
* used in cases where the Download Manager service doesn't delete the file
* from disk when cancelling. See bug 732924.
*/
_ensureLocalFileRemoved: function DVIC_ensureLocalFileRemoved()
{
try {
let localFile = this.dataItem.localFile;
if (localFile.exists()) {
localFile.remove(false);
}
} catch (ex) { }
}
};

View File

@ -68,8 +68,8 @@
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromListMenuItem"
label="&cmd.removeFromList.label;"
accesskey="&cmd.removeFromList.accesskey;"/>
label="&cmd.removeFromHistory.label;"
accesskey="&cmd.removeFromHistory.accesskey;"/>
<menuitem command="downloadsCmd_show"
class="downloadShowMenuItem"
#ifdef XP_MACOSX

View File

@ -63,6 +63,9 @@ const nsIDM = Ci.nsIDownloadManager;
const kDownloadsStringBundleUrl =
"chrome://browser/locale/downloads/downloads.properties";
const kPrefBdmScanWhenDone = "browser.download.manager.scanWhenDone";
const kPrefBdmAlertOnExeOpen = "browser.download.manager.alertOnEXEOpen";
const kDownloadsStringsRequiringFormatting = {
sizeWithUnits: true,
shortTimeLeftSeconds: true,
@ -396,6 +399,117 @@ this.DownloadsCommon = {
// never adding to the time left. Ensure that we never fall below one
// second left until all downloads are actually finished.
return aLastSeconds = Math.max(aSeconds, 1);
},
/**
* Opens a downloaded file.
* If you've a dataItem, you should call dataItem.openLocalFile.
* @param aFile
* the downloaded file to be opened.
* @param aMimeInfo
* the mime type info object. May be null.
* @param aOwnerWindow
* the window with which this action is associated.
*/
openDownloadedFile: function DC_openDownloadedFile(aFile, aMimeInfo, aOwnerWindow) {
if (!(aFile instanceof Ci.nsIFile))
throw new Error("aFile must be a nsIFile object");
if (aMimeInfo && !(aMimeInfo instanceof Ci.nsIMIMEInfo))
throw new Error("Invalid value passed for aMimeInfo");
if (!(aOwnerWindow instanceof Ci.nsIDOMWindow))
throw new Error("aOwnerWindow must be a dom-window object");
// Confirm opening executable files if required.
if (aFile.isExecutable()) {
let showAlert = true;
try {
showAlert = Services.prefs.getBoolPref(kPrefBdmAlertOnExeOpen);
} catch (ex) { }
// On Vista and above, we rely on native security prompting for
// downloaded content unless it's disabled.
if (DownloadsCommon.isWinVistaOrHigher) {
try {
if (Services.prefs.getBoolPref(kPrefBdmScanWhenDone)) {
showAlert = false;
}
} catch (ex) { }
}
if (showAlert) {
let name = this.dataItem.target;
let message =
DownloadsCommon.strings.fileExecutableSecurityWarning(name, name);
let title =
DownloadsCommon.strings.fileExecutableSecurityWarningTitle;
let dontAsk =
DownloadsCommon.strings.fileExecutableSecurityWarningDontAsk;
let checkbox = { value: false };
let open = Services.prompt.confirmCheck(aOwnerWindow, title, message,
dontAsk, checkbox);
if (!open) {
return;
}
Services.prefs.setBoolPref(kPrefBdmAlertOnExeOpen,
!checkbox.value);
}
}
// Actually open the file.
try {
if (aMimeInfo && aMimeInfo.preferredAction == aMimeInfo.useHelperApp) {
aMimeInfo.launchWithFile(aFile);
return;
}
}
catch(ex) { }
// If either we don't have the mime info, or the preferred action failed,
// attempt to launch the file directly.
try {
aFile.launch();
}
catch(ex) {
// If launch fails, try sending it through the system's external "file:"
// URL handler.
Cc["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Ci.nsIExternalProtocolService)
.loadUrl(NetUtil.newURI(aFile));
}
},
/**
* Show a donwloaded file in the system file manager.
* If you have a dataItem, use dataItem.showLocalFile.
*
* @param aFile
* a downloaded file.
*/
showDownloadedFile: function DC_showDownloadedFile(aFile) {
if (!(aFile instanceof Ci.nsIFile))
throw new Error("aFile must be a nsIFile object");
try {
// Show the directory containing the file and select the file.
aFile.reveal();
} catch (ex) {
// If reveal fails for some reason (e.g., it's not implemented on unix
// or the file doesn't exist), try using the parent if we have it.
let parent = aFile.parent;
if (parent) {
try {
// Open the parent directory to show where the file should be.
parent.launch();
} catch (ex) {
// If launch also fails (probably because it's not implemented), let
// the OS handler try to open the parent.
Cc["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Ci.nsIExternalProtocolService)
.loadUrl(NetUtil.newURI(parent));
}
}
}
}
};
@ -1212,6 +1326,101 @@ DownloadsDataItem.prototype = {
// file, though this may throw an exception if the path is invalid.
return new DownloadsLocalFileCtor(aFilename);
}
},
/**
* Open the target file for this download.
*
* @param aOwnerWindow
* The window with which the required action is associated.
* @throws if the file cannot be opened.
*/
openLocalFile: function DDI_openLocalFile(aOwnerWindow) {
this.getDownload(function(aDownload) {
DownloadsCommon.openDownloadedFile(this.localFile,
aDownload.MIMEInfo,
aOwnerWindow);
}.bind(this));
},
/**
* Show the downloaded file in the system file manager.
*/
showLocalFile: function DDI_showLocalFile() {
DownloadsCommon.showDownloadedFile(this.localFile);
},
/**
* Resumes the download if paused, pauses it if active.
* @throws if the download is not resumable or if has already done.
*/
togglePauseResume: function DDI_togglePauseResume() {
if (!this.inProgress || !this.resumable)
throw new Error("The given download cannot be paused or resumed");
this.getDownload(function(aDownload) {
if (this.inProgress) {
if (this.paused)
aDownload.resume();
else
aDownload.pause();
}
}.bind(this));
},
/**
* Attempts to retry the download.
* @throws if we cannot.
*/
retry: function DDI_retry() {
if (!this.canRetry)
throw new Error("Cannot rerty this download");
this.getDownload(function(aDownload) {
aDownload.retry();
});
},
/**
* Support function that deletes the local file for a download. This is
* used in cases where the Download Manager service doesn't delete the file
* from disk when cancelling. See bug 732924.
*/
_ensureLocalFileRemoved: function DDI__ensureLocalFileRemoved()
{
try {
let localFile = this.localFile;
if (localFile.exists()) {
localFile.remove(false);
}
} catch (ex) { }
},
/**
* Cancels the download.
* @throws if the download is already done.
*/
cancel: function() {
if (!this.inProgress)
throw new Error("Cannot cancel this download");
this.getDownload(function (aDownload) {
aDownload.cancel();
this._ensureLocalFileRemoved();
}.bind(this));
},
/**
* Remove the download.
*/
remove: function DDI_remove() {
this.getDownload(function (aDownload) {
if (this.inProgress) {
aDownload.cancel();
this._ensureLocalFileRemoved();
}
aDownload.remove();
}.bind(this));
}
};

View File

@ -20,6 +20,8 @@ PlacesViewBase.prototype = {
_viewElt: null,
get viewElt() this._viewElt,
get associatedElement() this._viewElt,
get controllers() this._viewElt.controllers,
// The xul element that represents the root container.

View File

@ -0,0 +1,45 @@
/* 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/. */
richlistitem.download button {
/* These buttons should never get focus, as that would "disable"
the downloads view controller (it's only used when the richlistbox
is focused). */
-moz-user-focus: none;
}
/*** Visibility of controls inside download items ***/
.download-state:-moz-any( [state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */
.downloadTypeIcon:not(.blockedIcon),
.download-state:not(:-moz-any([state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadTypeIcon.blockedIcon,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"], /* Paused */
[state="7"]) /* Scanning */)
.downloadProgress,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
.downloadCancel,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="3"]) /* Canceled */)
.downloadRetry,
.download-state:not( [state="1"] /* Finished */)
.downloadShow
{
visibility: hidden;
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0"?>
<!-- -*- Mode: HTML; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- -->
<!-- vim: set ts=2 et sw=2 tw=80: -->
<!-- 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/. -->
<!DOCTYPE bindings SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
<bindings id="downloadBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="download"
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<resources>
<stylesheet src="chrome://browser/content/places/download.css"/>
</resources>
<content orient="horizontal" align="center">
<xul:image class="downloadTypeIcon"
validate="always"
xbl:inherits="src=image"/>
<xul:image class="downloadTypeIcon blockedIcon"/>
<xul:vbox pack="center" flex="1">
<xul:description class="downloadTarget"
crop="center"
xbl:inherits="value=displayName,tooltiptext=displayName"/>
<xul:progressmeter anonid="progressmeter"
class="downloadProgress"
min="0"
max="100"
xbl:inherits="mode=progressmode,value=progress"/>
<xul:description class="downloadDetails"
style="width: &downloadDetails.width;"
crop="end"
xbl:inherits="value=status,tooltiptext=statusTip"/>
</xul:vbox>
<xul:stack>
<xul:button class="downloadButton downloadCancel"
command="downloadsCmd_cancel"
tooltiptext="&cmd.cancel.label;"/>
<xul:button class="downloadButton downloadRetry"
command="downloadsCmd_retry"
tooltiptext="&cmd.retry.label;"/>
<xul:button class="downloadButton downloadShow"
command="downloadsCmd_show"
tooltiptext="&cmd.show.label;"/>
</xul:stack>
</content>
</binding>
</bindings>

File diff suppressed because it is too large Load Diff

View File

@ -14,3 +14,33 @@ tree[type="places"] {
menupopup[placespopup="true"] {
-moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-base");
}
richlistitem.download {
-moz-binding: url('chrome://browser/content/places/download.xml#download');
}
.download-state:not( [state="0"] /* Downloading */)
.downloadPauseMenuItem,
.download-state:not( [state="4"] /* Paused */)
.downloadResumeMenuItem,
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
.download-state:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="5"], /* Starting (queued) */
[state="0"], /* Downloading */
[state="4"]) /* Paused */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator
{
display: none;
}

View File

@ -5,9 +5,13 @@
Components.utils.import("resource:///modules/MigrationUtils.jsm");
const DOWNLOADS_QUERY = "place:transition=" +
Components.interfaces.nsINavHistoryService.TRANSITION_DOWNLOAD +
"&sort=" +
Components.interfaces.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING;
var PlacesOrganizer = {
_places: null,
_content: null,
// IDs of fields from editBookmarkOverlay that should be hidden when infoBox
// is minimal. IDs should be kept in sync with the IDs of the elements
@ -32,8 +36,9 @@ var PlacesOrganizer = {
},
init: function PO_init() {
ContentArea.init();
this._places = document.getElementById("placesList");
this._content = document.getElementById("placeContent");
this._initFolderTree();
var leftPaneSelection = "AllBookmarks"; // default to all-bookmarks
@ -45,12 +50,6 @@ var PlacesOrganizer = {
this._backHistory.splice(0, this._backHistory.length);
document.getElementById("OrganizerCommand:Back").setAttribute("disabled", true);
var view = this._content.treeBoxObject.view;
if (view.rowCount > 0)
view.selection.select(0);
this._content.focus();
// Set up the search UI.
PlacesSearchBox.init();
@ -84,6 +83,13 @@ var PlacesOrganizer = {
#ifndef MOZ_PER_WINDOW_PRIVATE_BROWSING
gPrivateBrowsingListener.init();
#endif
// Select the first item in the content area view.
let view = ContentArea.currentView;
let root = view.result ? view.result.root : null;
if (root && root.containerOpen && root.childCount >= 0)
view.selectNode(root.getChild(0));
ContentArea.focus();
},
QueryInterface: function PO_QueryInterface(aIID) {
@ -139,9 +145,9 @@ var PlacesOrganizer = {
if (!this._places.hasSelection) {
// If no node was found for the given place: uri, just load it directly
this._content.place = aLocation;
ContentArea.currentPlace = aLocation;
}
this.onContentTreeSelect();
this.updateDetailsPane();
// update navigation commands
if (this._backHistory.length == 0)
@ -201,8 +207,8 @@ var PlacesOrganizer = {
// If either the place of the content tree in the right pane has changed or
// the user cleared the search box, update the place, hide the search UI,
// and update the back/forward buttons by setting location.
if (this._content.place != placeURI || !resetSearchBox) {
this._content.place = placeURI;
if (ContentArea.currentPlace != placeURI || !resetSearchBox) {
ContentArea.currentPlace = placeURI;
this.location = node.uri;
}
@ -221,8 +227,7 @@ var PlacesOrganizer = {
PlacesSearchBox.searchFilter.reset();
this._setSearchScopeForNode(node);
if (this._places.treeBoxObject.focused)
this._fillDetailsPane([node]);
this.updateDetailsPane();
},
/**
@ -247,50 +252,39 @@ var PlacesOrganizer = {
},
/**
* Handle clicks on the tree.
* Handle clicks on the places list.
* Single Left click, right click or modified click do not result in any
* special action, since they're related to selection.
* @param aEvent
* The mouse event.
*/
onTreeClick: function PO_onTreeClick(aEvent) {
onPlacesListClick: function PO_onPlacesListClick(aEvent) {
// Only handle clicks on tree children.
if (aEvent.target.localName != "treechildren")
return;
var currentView = aEvent.currentTarget;
var selectedNode = currentView.selectedNode;
if (selectedNode) {
var doubleClickOnFlatList = (aEvent.button == 0 && aEvent.detail == 2 &&
aEvent.target.parentNode.flatList);
var middleClick = (aEvent.button == 1 && aEvent.detail == 1);
if (PlacesUtils.nodeIsURI(selectedNode) &&
(doubleClickOnFlatList || middleClick)) {
// Open associated uri in the browser.
PlacesOrganizer.openSelectedNode(aEvent);
}
else if (middleClick &&
PlacesUtils.nodeIsContainer(selectedNode)) {
let node = this._places.selectedNode;
if (node) {
let middleClick = aEvent.button == 1 && aEvent.detail == 1;
if (middleClick && PlacesUtils.nodeIsContainer(node)) {
// The command execution function will take care of seeing if the
// selection is a folder or a different container type, and will
// load its contents in tabs.
PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent, currentView);
PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent, this._places);
}
}
},
/**
* Handle focus changes on the trees.
* When moving focus between panes we should update the details pane contents.
* @param aEvent
* The mouse event.
* Handle focus changes on the places list and the current content view.
*/
onTreeFocus: function PO_onTreeFocus(aEvent) {
var currentView = aEvent.currentTarget;
var selectedNodes = currentView.selectedNode ? [currentView.selectedNode] :
this._content.selectedNodes;
this._fillDetailsPane(selectedNodes);
updateDetailsPane: function PO_updateDetailsPane() {
let view = PlacesUIUtils.getViewForNode(document.activeElement);
if (view) {
let selectedNodes = view.selectedNode ?
[view.selectedNode] : view.selectedNodes;
this._fillDetailsPane(selectedNodes);
}
},
openFlatContainer: function PO_openFlatContainerFlatContainer(aContainer) {
@ -300,17 +294,12 @@ var PlacesOrganizer = {
this._places.selectPlaceURI(aContainer.uri);
},
openSelectedNode: function PO_openSelectedNode(aEvent) {
PlacesUIUtils.openNodeWithEvent(this._content.selectedNode, aEvent,
this._content);
},
/**
* Returns the options associated with the query currently loaded in the
* main places pane.
*/
getCurrentOptions: function PO_getCurrentOptions() {
return PlacesUtils.asQuery(this._content.result.root).queryOptions;
return PlacesUtils.asQuery(ContentArea.currentView.result.root).queryOptions;
},
/**
@ -318,7 +307,7 @@ var PlacesOrganizer = {
* main places pane.
*/
getCurrentQueries: function PO_getCurrentQueries() {
return PlacesUtils.asQuery(this._content.result.root).getQueries();
return PlacesUtils.asQuery(ContentArea.currentView.result.root).getQueries();
},
/**
@ -564,11 +553,6 @@ var PlacesOrganizer = {
canvas.height = height;
},
onContentTreeSelect: function PO_onContentTreeSelect() {
if (this._content.treeBoxObject.focused)
this._fillDetailsPane(this._content.selectedNodes);
},
_fillDetailsPane: function PO__fillDetailsPane(aNodeList) {
var infoBox = document.getElementById("infoBox");
var detailsDeck = document.getElementById("detailsDeck");
@ -671,10 +655,15 @@ var PlacesOrganizer = {
else {
detailsDeck.selectedIndex = 0;
infoBox.hidden = true;
var selectItemDesc = document.getElementById("selectItemDescription");
var itemsCountLabel = document.getElementById("itemsCountText");
var rowCount = this._content.treeBoxObject.view.rowCount;
if (rowCount == 0) {
let selectItemDesc = document.getElementById("selectItemDescription");
let itemsCountLabel = document.getElementById("itemsCountText");
let itemsCount = 0;
if (ContentArea.currentView.result) {
let rootNode = ContentArea.currentView.result.root;
if (rootNode.containerOpen)
itemsCount = rootNode.childCount;
}
if (itemsCount == 0) {
selectItemDesc.hidden = true;
itemsCountLabel.value = PlacesUIUtils.getString("detailsPane.noItems");
}
@ -682,7 +671,7 @@ var PlacesOrganizer = {
selectItemDesc.hidden = false;
itemsCountLabel.value =
PlacesUIUtils.getPluralString("detailsPane.itemsCountLabel",
rowCount, [rowCount]);
itemsCount, [itemsCount]);
}
}
},
@ -779,14 +768,14 @@ var PlacesSearchBox = {
return;
}
var currentOptions = PO.getCurrentOptions();
var content = PO._content;
let currentView = ContentArea.currentView;
let currentOptions = PO.getCurrentOptions();
// Search according to the current scope, which was set by
// PQB_setScope()
switch (PlacesSearchBox.filterCollection) {
case "bookmarks":
content.applyFilter(filterString, this.folders);
currentView.applyFilter(filterString, this.folders);
break;
case "history":
if (currentOptions.queryType != Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
@ -797,13 +786,14 @@ var PlacesSearchBox = {
options.resultType = currentOptions.RESULT_TYPE_URI;
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
options.includeHidden = true;
content.load([query], options);
currentView.load([query], options);
}
else {
content.applyFilter(filterString, null, true);
currentView.applyFilter(filterString, null, true);
}
break;
case "downloads": {
case "downloads":
if (currentView == ContentTree.view) {
let query = PlacesUtils.history.getNewQuery();
query.searchTerms = filterString;
query.setTransitions([Ci.nsINavHistoryService.TRANSITION_DOWNLOAD], 1);
@ -812,16 +802,19 @@ var PlacesSearchBox = {
options.resultType = currentOptions.RESULT_TYPE_URI;
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
options.includeHidden = true;
content.load([query], options);
currentView.load([query], options);
}
else {
// The new downloads view doesn't use places for searching downloads.
currentView.searchTerm = filterString;
}
break;
}
default:
throw "Invalid filterCollection on search";
break;
default:
throw "Invalid filterCollection on search";
}
// Update the details panel
PlacesOrganizer.onContentTreeSelect();
PlacesOrganizer.updateDetailsPane();
},
/**
@ -1251,3 +1244,94 @@ let gPrivateBrowsingListener = {
}
};
#endif
let ContentArea = {
init: function CA_init() {
this._deck = document.getElementById("placesViewsDeck");
this._specialViews = new Map();
ContentTree.init();
},
_shouldUseNewDownloadsView: function CA_shouldUseNewDownloadsView() {
try {
return Services.prefs.getBoolPref("browser.library.useNewDownloadsView");
}
catch(ex) { }
return false;
},
getContentViewForQueryString:
function CA_getContentViewForQueryString(aQueryString) {
if (this._specialViews.has(aQueryString))
return this._specialViews.get(aQueryString);
if (aQueryString == DOWNLOADS_QUERY && this._shouldUseNewDownloadsView()) {
let view = new DownloadsPlacesView(document.getElementById("downloadsRichListBox"));
this.setContentViewForQueryString(aQueryString, view);
return view;
}
return ContentTree.view;
},
setContentViewForQueryString:
function CA_setContentViewForQueryString(aQueryString, aView) {
this._specialViews.set(aQueryString, aView);
},
get currentView() PlacesUIUtils.getViewForNode(this._deck.selectedPanel),
set currentView(aView) {
if (this.currentView != aView)
this._deck.selectedPanel = aView.associatedElement;
return aView;
},
get currentPlace() this.currentView.place,
set currentPlace(aQueryString) {
this.currentView = this.getContentViewForQueryString(aQueryString);
this.currentView.place = aQueryString;
return aQueryString;
},
focus: function() {
this._deck.selectedPanel.focus();
}
};
let ContentTree = {
init: function CT_init() {
this._view = document.getElementById("placeContent");
},
get view() this._view,
openSelectedNode: function CT_openSelectedNode(aEvent) {
let view = this.view;
PlacesUIUtils.openNodeWithEvent(view.selectedNode, aEvent, view);
},
onClick: function CT_onClick(aEvent) {
// Only handle clicks on tree children.
if (aEvent.target.localName != "treechildren")
return;
let node = this.view.selectedNode;
if (node) {
let doubleClick = aEvent.button == 0 && aEvent.detail == 2;
let middleClick = aEvent.button == 1 && aEvent.detail == 1;
if (PlacesUtils.nodeIsURI(node) && (doubleClick || middleClick)) {
// Open associated uri in the browser.
this.openSelectedNode(aEvent);
}
else if (middleClick && PlacesUtils.nodeIsContainer(node)) {
// The command execution function will take care of seeing if the
// selection is a folder or a different container type, and will
// load its contents in tabs.
PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this.view);
}
}
},
onKeyPress: function CT_onKeyPress(aEvent) {
if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
this.openSelectedNode(aEvent);
}
};

View File

@ -10,6 +10,7 @@
<?xml-stylesheet href="chrome://global/skin/"?>
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
<?xml-stylesheet href="chrome://browser/skin/places/organizer.css"?>
<?xml-stylesheet href="chrome://browser/skin/downloads/downloads.css"?>
<?xul-overlay href="chrome://browser/content/places/editBookmarkOverlay.xul"?>
@ -28,6 +29,8 @@
%editMenuOverlayDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
<!ENTITY % downloadsDTD SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
%downloadsDTD;
]>
<window id="places"
@ -42,12 +45,16 @@
toggletoolbar="true"
persist="width height screenX screenY sizemode">
<script type="application/javascript"
src="chrome://browser/content/places/downloadsView.js"/>
<script type="application/javascript"
src="chrome://browser/content/places/places.js"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<script type="application/javascript"
src="chrome://browser/content/places/editBookmarkOverlay.js"/>
<script type="application/javascript"
src="chrome://global/content/contentAreaUtils.js"/>
<stringbundleset id="placesStringSet">
<stringbundle id="brandStrings" src="chrome://branding/locale/brand.properties"/>
@ -344,8 +351,8 @@
type="places"
hidecolumnpicker="true" context="placesContext"
onselect="PlacesOrganizer.onPlaceSelected(true);"
onclick="PlacesOrganizer.onTreeClick(event);"
onfocus="PlacesOrganizer.onTreeFocus(event);"
onclick="PlacesOrganizer.onPlacesListClick(event);"
onfocus="PlacesOrganizer.updateDetailsPane(event);"
seltype="single"
persist="width"
width="200"
@ -358,49 +365,58 @@
</tree>
<splitter collapse="none" persist="state"></splitter>
<vbox id="contentView" flex="4">
<tree id="placeContent"
class="plain placesTree"
context="placesContext"
hidecolumnpicker="true"
flex="1"
type="places"
flatList="true"
enableColumnDrag="true"
onkeypress="if (event.keyCode == KeyEvent.DOM_VK_RETURN) PlacesOrganizer.openSelectedNode(event);"
onopenflatcontainer="PlacesOrganizer.openFlatContainer(aContainer);"
onselect="PlacesOrganizer.onContentTreeSelect();"
onfocus="PlacesOrganizer.onTreeFocus(event);"
onclick="PlacesOrganizer.onTreeClick(event);">
<treecols id="placeContentColumns" context="placesColumnsContext">
<treecol label="&col.name.label;" id="placesContentTitle" anonid="title" flex="5" primary="true" ordinal="1"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.tags.label;" id="placesContentTags" anonid="tags" flex="2"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.url.label;" id="placesContentUrl" anonid="url" flex="5"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.lastvisit.label;" id="placesContentDate" anonid="date" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.visitcount.label;" id="placesContentVisitCount" anonid="visitCount" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.keyword.label;" id="placesContentKeyword" anonid="keyword" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.description.label;" id="placesContentDescription" anonid="description" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.dateadded.label;" id="placesContentDateAdded" anonid="dateAdded" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.lastmodified.label;" id="placesContentLastModified" anonid="lastModified" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
</treecols>
<treechildren flex="1"/>
</tree>
<deck id="placesViewsDeck"
selectedIndex="0"
flex="1">
<tree id="placeContent"
class="plain placesTree"
context="placesContext"
hidecolumnpicker="true"
flex="1"
type="places"
flatList="true"
enableColumnDrag="true"
onfocus="PlacesOrganizer.updateDetailsPane(event)"
onselect="PlacesOrganizer.updateDetailsPane(event)"
onkeypress="ContentTree.onKeyPress(event);"
onopenflatcontainer="PlacesOrganizer.openFlatContainer(aContainer);"
onclick="ContentTree.onClick(event);">
<treecols id="placeContentColumns" context="placesColumnsContext">
<treecol label="&col.name.label;" id="placesContentTitle" anonid="title" flex="5" primary="true" ordinal="1"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.tags.label;" id="placesContentTags" anonid="tags" flex="2"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.url.label;" id="placesContentUrl" anonid="url" flex="5"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.lastvisit.label;" id="placesContentDate" anonid="date" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.visitcount.label;" id="placesContentVisitCount" anonid="visitCount" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.keyword.label;" id="placesContentKeyword" anonid="keyword" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.description.label;" id="placesContentDescription" anonid="description" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.dateadded.label;" id="placesContentDateAdded" anonid="dateAdded" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
<splitter class="tree-splitter"/>
<treecol label="&col.lastmodified.label;" id="placesContentLastModified" anonid="lastModified" flex="1" hidden="true"
persist="width hidden ordinal sortActive sortDirection"/>
</treecols>
<treechildren flex="1"/>
</tree>
<richlistbox flex="1"
seltype="multiple"
id="downloadsRichListBox" context="downloadsContextMenu"
onkeypress="return this._placesView.onKeyPress(event);"
oncontextmenu="return this._placesView.onContextMenu(event);"/>
</deck>
<deck id="detailsDeck" style="height: 11em;">
<vbox id="itemsCountBox" align="center">
<spacer flex="3"/>
@ -434,4 +450,61 @@
</deck>
</vbox>
</hbox>
<commandset id="downloadCommands"
commandupdater="true"
events="focus,select,contextmenu"
oncommandupdate="goUpdatePlacesCommands(); goUpdateDownloadCommands();">
<command id="downloadsCmd_pauseResume"
oncommand="goDoCommand('downloadsCmd_pauseResume')"/>
<command id="downloadsCmd_cancel"
oncommand="goDoCommand('downloadsCmd_cancel')"/>
<command id="downloadsCmd_open"
oncommand="goDoCommand('downloadsCmd_open')"/>
<command id="downloadsCmd_show"
oncommand="goDoCommand('downloadsCmd_show')"/>
<command id="downloadsCmd_retry"
oncommand="goDoCommand('downloadsCmd_retry')"/>
<command id="downloadsCmd_openReferrer"
oncommand="goDoCommand('downloadsCmd_openReferrer')"/>
</commandset>
<menupopup id="downloadsContextMenu"
class="download-state">
<menuitem command="downloadsCmd_pauseResume"
class="downloadPauseMenuItem"
label="&cmd.pause.label;"
accesskey="&cmd.pause.accesskey;"/>
<menuitem command="downloadsCmd_pauseResume"
class="downloadResumeMenuItem"
label="&cmd.resume.label;"
accesskey="&cmd.resume.accesskey;"/>
<menuitem command="downloadsCmd_cancel"
class="downloadCancelMenuItem"
label="&cmd.cancel.label;"
accesskey="&cmd.cancel.accesskey;"/>
<menuitem command="cmd_delete"
class="downloadRemoveFromHistoryMenuItem"
label="&cmd.removeFromHistory.label;"
accesskey="&cmd.removeFromHistory.accesskey;"/>
<menuitem command="downloadsCmd_show"
class="downloadShowMenuItem"
#ifdef XP_MACOSX
label="&cmd.showMac.label;"
accesskey="&cmd.showMac.accesskey;"
#else
label="&cmd.show.label;"
accesskey="&cmd.show.accesskey;"
#endif
/>
<menuseparator class="downloadCommandsSeparator"/>
<menuitem command="downloadsCmd_openReferrer"
label="&cmd.goToDownloadPage.label;"
accesskey="&cmd.goToDownloadPage.accesskey;"/>
<menuitem command="cmd_copy"
label="&cmd.copyDownloadLink.label;"
accesskey="&cmd.copyDownloadLink.accesskey;"/>
</menupopup>
</window>

View File

@ -56,6 +56,10 @@
]]></setter>
</property>
<property name="associatedElement"
readonly="true"
onget="return this"/>
<method name="applyFilter">
<parameter name="filterString"/>
<parameter name="folderRestrict"/>

View File

@ -8,6 +8,9 @@ browser.jar:
content/browser/places/bookmarkProperties2.xul (content/bookmarkProperties.xul)
* content/browser/places/places.xul (content/places.xul)
* content/browser/places/places.js (content/places.js)
content/browser/places/downloadsView.js (content/downloadsView.js)
content/browser/places/download.xml (content/download.xml)
content/browser/places/download.css (content/download.css)
content/browser/places/places.css (content/places.css)
content/browser/places/organizer.css (content/organizer.css)
content/browser/places/bookmarkProperties.xul (content/bookmarkProperties.xul)

View File

@ -622,7 +622,7 @@ this.PlacesUIUtils = {
openNodeWithEvent:
function PUIU_openNodeWithEvent(aNode, aEvent, aView) {
let window = aView.ownerWindow;
this._openNodeIn(aNode, window.whereToOpenLink(aEvent), window);
this._openNodeIn(aNode, window.whereToOpenLink(aEvent, false, true), window);
},
/**

View File

@ -21,6 +21,7 @@ const MOZURISPEC = "http://mozilla.com/";
let gLibrary;
let PlacesOrganizer;
let ContentTree;
function test() {
waitForExplicitFinish();
@ -34,6 +35,9 @@ function onLibraryReady() {
PlacesOrganizer = gLibrary.PlacesOrganizer;
ok(PlacesOrganizer, "Places organizer in scope");
ContentTree = gLibrary.ContentTree;
ok(ContentTree, "ContentTree is in scope");
tests.makeHistVisit();
tests.makeTag();
tests.focusTag();
@ -101,12 +105,12 @@ let tests = {
PlacesUtils.asContainer(histContainer);
histContainer.containerOpen = true;
PlacesOrganizer._places.selectNode(histContainer.getChild(0));
let histNode = PlacesOrganizer._content.view.nodeForTreeIndex(0);
PlacesOrganizer._content.selectNode(histNode);
let histNode = ContentTree.view.view.nodeForTreeIndex(0);
ContentTree.view.selectNode(histNode);
is(histNode.uri, MOZURISPEC,
"historyNode exists: " + histNode.uri);
// copy the history node
PlacesOrganizer._content.controller.copy();
ContentTree.view.controller.copy();
},
historyNode: function (){
@ -116,7 +120,7 @@ let tests = {
PlacesUtils.asContainer(histContainer);
histContainer.containerOpen = true;
PlacesOrganizer._places.selectNode(histContainer.getChild(0));
let histNode = PlacesOrganizer._content.view.nodeForTreeIndex(0);
let histNode = ContentTree.view.view.nodeForTreeIndex(0);
ok(histNode, "histNode exists: " + histNode.title);
// check to see if the history node is tagged!
let tags = PlacesUtils.tagging.getTagsForURI(NetUtil.newURI(MOZURISPEC));
@ -133,8 +137,8 @@ let tests = {
// is the bookmark visible in the UI?
// get the Unsorted Bookmarks node
PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
// now we can see what is in the _content tree
let unsortedNode = PlacesOrganizer._content.view.nodeForTreeIndex(1);
// now we can see what is in the ContentTree tree
let unsortedNode = ContentTree.view.view.nodeForTreeIndex(1);
ok(unsortedNode, "unsortedNode is not null: " + unsortedNode.uri);
is(unsortedNode.uri, MOZURISPEC, "node uri's are the same");
},

View File

@ -7,6 +7,7 @@ const TEST_URL = "http://example.com/";
let gLibrary;
let gItemId;
let PlacesOrganizer;
let ContentTree;
function test() {
waitForExplicitFinish();
@ -15,11 +16,13 @@ function test() {
function onLibraryReady() {
PlacesOrganizer = gLibrary.PlacesOrganizer;
ContentTree = gLibrary.ContentTree;
// Sanity checks.
ok(PlacesUtils, "PlacesUtils in scope");
ok(PlacesUIUtils, "PlacesUIUtils in scope");
ok(PlacesOrganizer, "PlacesOrganizer in scope");
ok(ContentTree, "ContentTree is in scope");
gItemId = PlacesUtils.bookmarks.insertBookmark(
PlacesUtils.toolbarFolderId, NetUtil.newURI(TEST_URL),
@ -41,21 +44,21 @@ function selectBookmarkIn(aLeftPaneQuery) {
is(PlacesUtils.bookmarks.getFolderIdForItem(gItemId), rootId,
"Bookmark has the right parent");
info("Selecting the bookmark in the right pane");
PlacesOrganizer._content.selectItems([gItemId]);
let bookmarkNode = PlacesOrganizer._content.selectedNode;
ContentTree.view.selectItems([gItemId]);
let bookmarkNode = ContentTree.view.selectedNode;
is(bookmarkNode.uri, TEST_URL, "Found the expected bookmark");
}
function cutSelection() {
info("Cutting selection");
PlacesOrganizer._content.controller.cut();
ContentTree.view.controller.cut();
}
function pasteClipboard(aLeftPaneQuery) {
info("Selecting " + aLeftPaneQuery + " in the left pane");
PlacesOrganizer.selectLeftPaneQuery(aLeftPaneQuery);
info("Pasting clipboard");
PlacesOrganizer._content.controller.paste();
ContentTree.view.controller.paste();
}
function onClipboardReady() {

View File

@ -69,19 +69,20 @@ gTests.push({
desc: "Ensure correct selection and functionality in Library",
run: function() {
let PO = gLibrary.PlacesOrganizer;
let ContentTree = gLibrary.ContentTree;
// Move selection forth and back.
PO.selectLeftPaneQuery("History");
PO.selectLeftPaneQuery("UnfiledBookmarks");
// Now select the "keepme" folder in the right pane and delete it.
PO._content.selectNode(PO._content.result.root.getChild(0));
is(PO._content.selectedNode.title, "keepme",
ContentTree.view.selectNode(ContentTree.view.result.root.getChild(0));
is(ContentTree.view.selectedNode.title, "keepme",
"Found folder in content pane");
// Test live update.
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
makeURI(TEST_URL),
PlacesUtils.bookmarks.DEFAULT_INDEX,
"bm");
is(PO._content.result.root.childCount, 2,
is(ContentTree.view.result.root.childCount, 2,
"Right pane was correctly updated");
nextTest();
}

View File

@ -18,6 +18,7 @@ gTests.push({
desc: "Bug 430148 - Remove or hide the more/less button in details pane...",
run: function() {
var PO = gLibrary.PlacesOrganizer;
let ContentTree = gLibrary.ContentTree;
var infoBoxExpanderWrapper = getAndCheckElmtById("infoBoxExpanderWrapper");
// add a visit to browser history
@ -57,7 +58,7 @@ gTests.push({
checkAddInfoFieldsCollapsed(PO);
// open history item
var view = PO._content.treeBoxObject.view;
var view = ContentTree.view.treeBoxObject.view;
ok(view.rowCount > 0, "History item exists.");
view.selection.select(0);
ok(infoBoxExpanderWrapper.hidden,
@ -94,7 +95,7 @@ gTests.push({
checkAddInfoFieldsNotCollapsed(PO);
// open first bookmark
var view = PO._content.treeBoxObject.view;
var view = ContentTree.view.treeBoxObject.view;
ok(view.rowCount > 0, "Bookmark item exists.");
view.selection.select(0);
checkInfoBoxSelected(PO);

View File

@ -88,7 +88,7 @@ gTests.push({
isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
"We correctly have selection in the Library left pane");
// Get our bookmark in the right pane.
var bookmarkNode = gLibrary.PlacesOrganizer._content.view.nodeForTreeIndex(0);
var bookmarkNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
is(bookmarkNode.uri, this.URIs[0], "Found bookmark in the right pane");
},
@ -130,7 +130,7 @@ gTests.push({
isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
"We correctly have selection in the Library left pane");
// Get our bookmark in the right pane.
var folderNode = gLibrary.PlacesOrganizer._content.view.nodeForTreeIndex(0);
var folderNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
is(folderNode.title, "Folder", "Found folder in the right pane");
},
@ -187,7 +187,7 @@ gTests.push({
isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
"We correctly have selection in the Library left pane");
// Get our bookmark in the right pane.
var folderNode = gLibrary.PlacesOrganizer._content.view.nodeForTreeIndex(0);
var folderNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
is(folderNode.title, "Query", "Found query in the right pane");
},
@ -243,7 +243,7 @@ function runNextTest() {
// Middle click on first node in the content tree of the Library.
gLibrary.focus();
waitForFocus(function() {
mouseEventOnCell(gLibrary.PlacesOrganizer._content, 0, 0, { button: 1 });
mouseEventOnCell(gLibrary.ContentTree.view, 0, 0, { button: 1 });
}, gLibrary);
}
else {

View File

@ -3711,9 +3711,6 @@ let SessionStoreInternal = {
for (let i = oState.windows.length - 1; i >= 0; i--) {
if (oState.windows[i].isPrivate) {
oState.windows.splice(i, 1);
if (oState.selectedWindow >= i) {
oState.selectedWindow--;
}
}
}
for (let i = oState._closedWindows.length - 1; i >= 0; i--) {

View File

@ -137,7 +137,6 @@ ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
MOCHITEST_BROWSER_FILES += \
browser_354894_perwindowpb.js \
browser_394759_perwindowpb.js \
browser_819510_perwindowpb.js \
$(NULL)
else
MOCHITEST_BROWSER_FILES += \

View File

@ -1,171 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const originalState = ss.getBrowserState();
/** Private Browsing Test for Bug 819510 **/
function test() {
waitForExplicitFinish();
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.sessionstore.interval");
ss.setBrowserState(originalState);
});
runNextTest();
}
let tests = [
test_1,
test_2,
test_3,
];
const testState = {
windows: [{
tabs: [
{ entries: [{ url: "about:blank" }] },
]
}]
};
function runNextTest() {
// Set an empty state
let windowsEnum = Services.wm.getEnumerator("navigator:browser");
while (windowsEnum.hasMoreElements()) {
let currentWindow = windowsEnum.getNext();
if (currentWindow != window) {
currentWindow.close();
}
}
// Run the next test, or finish
if (tests.length) {
let currentTest = tests.shift();
waitForBrowserState(testState, currentTest);
}
else {
Services.prefs.clearUserPref("browser.sessionstore.interval");
ss.setBrowserState(originalState);
finish();
}
}
// Test opening default mochitest-normal-private-normal-private windows
// (saving the state with last window being private)
function test_1() {
testOnWindow(false, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/1");
testOnWindow(true, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/2");
testOnWindow(false, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/3");
testOnWindow(true, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/4");
let curState = JSON.parse(ss.getBrowserState());
is (curState.windows.length, 5, "Browser has opened 5 windows");
is (curState.windows[2].isPrivate, true, "Window is private");
is (curState.windows[4].isPrivate, true, "Last window is private");
is (curState.selectedWindow, 5, "Last window opened is the one selected");
Services.obs.addObserver(function observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(observe, aTopic);
aSubject.QueryInterface(Ci.nsISupportsString);
let state = JSON.parse(aSubject.data);
is(state.windows.length, 3,
"sessionstore state: 3 windows in data being writted to disk");
is (state.selectedWindow, 3,
"Selected window is updated to match one of the saved windows");
state.windows.forEach(function(win) {
is(!win.isPrivate, true, "Saved window is not private");
});
is(state._closedWindows.length, 0,
"sessionstore state: no closed windows in data being writted to disk");
runNextTest();
}, "sessionstore-state-write", false);
Services.prefs.setIntPref("browser.sessionstore.interval", 0);
});
});
});
});
}
// Test opening default mochitest window + 2 private windows
function test_2() {
testOnWindow(true, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/1");
testOnWindow(true, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/2");
let curState = JSON.parse(ss.getBrowserState());
is (curState.windows.length, 3, "Browser has opened 3 windows");
is (curState.windows[1].isPrivate, true, "Window 1 is private");
is (curState.windows[2].isPrivate, true, "Window 2 is private");
is (curState.selectedWindow, 3, "Last window opened is the one selected");
Services.obs.addObserver(function observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(observe, aTopic);
aSubject.QueryInterface(Ci.nsISupportsString);
let state = JSON.parse(aSubject.data);
is(state.windows.length, 1,
"sessionstore state: 1 windows in data being writted to disk");
is (state.selectedWindow, 1,
"Selected window is updated to match one of the saved windows");
is(state._closedWindows.length, 0,
"sessionstore state: no closed windows in data being writted to disk");
runNextTest();
}, "sessionstore-state-write", false);
Services.prefs.setIntPref("browser.sessionstore.interval", 0);
});
});
}
// Test opening default-normal-private-normal windows and closing a normal window
function test_3() {
testOnWindow(false, function(normalWindow) {
normalWindow.gBrowser.addTab("http://www.example.com/1");
testOnWindow(true, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/2");
testOnWindow(false, function(aWindow) {
aWindow.gBrowser.addTab("http://www.example.com/3");
let curState = JSON.parse(ss.getBrowserState());
is (curState.windows.length, 4, "Browser has opened 4 windows");
is (curState.windows[2].isPrivate, true, "Window 2 is private");
is (curState.selectedWindow, 4, "Last window opened is the one selected");
normalWindow.close();
Services.obs.addObserver(function observe(aSubject, aTopic, aData) {
Services.obs.removeObserver(observe, aTopic);
aSubject.QueryInterface(Ci.nsISupportsString);
let state = JSON.parse(aSubject.data);
is(state.windows.length, 2,
"sessionstore state: 2 windows in data being writted to disk");
is (state.selectedWindow, 2,
"Selected window is updated to match one of the saved windows");
state.windows.forEach(function(win) {
is(!win.isPrivate, true, "Saved window is not private");
});
is(state._closedWindows.length, 1,
"sessionstore state: 1 closed window in data being writted to disk");
state._closedWindows.forEach(function(win) {
is(!win.isPrivate, true, "Closed window is not private");
});
runNextTest();
}, "sessionstore-state-write", false);
Services.prefs.setIntPref("browser.sessionstore.interval", 0);
});
});
});
}
function testOnWindow(aIsPrivate, aCallback) {
let win = OpenBrowserWindow({private: aIsPrivate});
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
executeSoon(function() { aCallback(win); });
}, false);
}

View File

@ -84,7 +84,6 @@ MOCHITEST_BROWSER_TESTS = \
browser_dbg_iframes.js \
browser_dbg_pause-exceptions.js \
browser_dbg_multiple-windows.js \
browser_dbg_bfcache.js \
browser_dbg_breakpoint-new-script.js \
browser_dbg_bug737803_editor_actual_location.js \
browser_dbg_progress-listener-bug.js \
@ -93,6 +92,14 @@ MOCHITEST_BROWSER_TESTS = \
head.js \
$(NULL)
ifneq ($(OS_ARCH),WINNT)
MOCHITEST_BROWSER_TESTS += \
browser_dbg_bfcache.js \
$(NULL)
else
$(filter disabled-temporarily--bug-774619, browser_dbg_bfcache.js)
endif
MOCHITEST_BROWSER_PAGES = \
browser_dbg_tab1.html \
browser_dbg_tab2.html \

View File

@ -8,7 +8,7 @@ Cu.import("resource:///modules/devtools/LayoutHelpers.jsm", tempScope);
let LayoutHelpers = tempScope.LayoutHelpers;
Cu.import("resource:///modules/devtools/Target.jsm", tempScope);
let TargetFactory = tempScope.TargetFactory;
Components.utils.import("resource:///modules/devtools/Console.jsm", tempScope);
Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
let console = tempScope.console;
// Import the GCLI test helper

View File

@ -8,7 +8,7 @@ const Cu = Components.utils;
Cu.import("resource:///modules/devtools/ProfilerController.jsm");
Cu.import("resource://gre/modules/commonjs/promise/core.js");
Cu.import("resource://gre/modules/devtools/EventEmitter.jsm");
Cu.import("resource:///modules/devtools/EventEmitter.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
this.EXPORTED_SYMBOLS = ["ProfilerPanel"];
@ -390,4 +390,4 @@ ProfilerPanel.prototype = {
this.emit("destroyed");
}
};
};

View File

@ -9,7 +9,7 @@ const TEST_HOST = 'mochi.test:8888';
let tempScope = {};
Cu.import("resource:///modules/devtools/Target.jsm", tempScope);
let TargetFactory = tempScope.TargetFactory;
Components.utils.import("resource:///modules/devtools/Console.jsm", tempScope);
Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
let console = tempScope.console;
let gChromeWindow; //StyleEditorChrome window

View File

@ -13,7 +13,7 @@ let CssHtmlTree = tempScope.CssHtmlTree;
let gDevTools = tempScope.gDevTools;
Cu.import("resource:///modules/devtools/Target.jsm", tempScope);
let TargetFactory = tempScope.TargetFactory;
Components.utils.import("resource:///modules/devtools/Console.jsm", tempScope);
Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
let console = tempScope.console;
let browser, hudId, hud, hudBox, filterBox, outputNode, cs;

View File

@ -12,7 +12,7 @@ Cu.import("resource:///modules/devtools/gDevTools.jsm", tempScope);
let gDevTools = tempScope.gDevTools;
Cu.import("resource:///modules/devtools/Target.jsm", tempScope);
let TargetFactory = tempScope.TargetFactory;
Components.utils.import("resource:///modules/devtools/Console.jsm", tempScope);
Components.utils.import("resource://gre/modules/devtools/Console.jsm", tempScope);
let console = tempScope.console;
const WEBCONSOLE_STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";

View File

@ -60,8 +60,8 @@
<!ENTITY cmd.goToDownloadPage.accesskey "G">
<!ENTITY cmd.copyDownloadLink.label "Copy Download Link">
<!ENTITY cmd.copyDownloadLink.accesskey "L">
<!ENTITY cmd.removeFromList.label "Remove From List">
<!ENTITY cmd.removeFromList.accesskey "e">
<!ENTITY cmd.removeFromHistory.label "Remove From History">
<!ENTITY cmd.removeFromHistory.accesskey "e">
<!ENTITY cmd.clearList.label "Clear List">
<!ENTITY cmd.clearList.accesskey "a">

View File

@ -26,7 +26,7 @@
#downloadsPanel[hasdownloads] > #downloadsFooter {
border-top: 1px solid ThreeDShadow;
background-image: -moz-linear-gradient(hsla(0,0%,0%,.15), hsla(0,0%,0%,.08) 6px);
background-image: linear-gradient(hsla(0,0%,0%,.15), hsla(0,0%,0%,.08) 6px);
}
#downloadsHistory > .button-box {
@ -136,7 +136,7 @@ richlistitem[type="download"][state="1"]:hover {
border-top: 1px solid hsla(0,0%,100%,.3);
border-bottom: 1px solid hsla(0,0%,0%,.2);
background-color: Highlight;
background-image: -moz-linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,100%,0));
background-image: linear-gradient(hsla(0,0%,100%,.1), hsla(0,0%,100%,0));
color: HighlightText;
cursor: pointer;
}
@ -300,7 +300,7 @@ toolbar[iconsize="large"] > #downloads-indicator[attention] > #downloads-indicat
-moz-appearance: none;
min-width: 0;
min-height: 0;
background-image: -moz-linear-gradient(#505050, #575757);
background-image: linear-gradient(#505050, #575757);
border: 1px solid;
border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
-moz-border-start: none;
@ -312,5 +312,5 @@ toolbar[iconsize="large"] > #downloads-indicator[attention] > #downloads-indicat
}
#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
background-image: -moz-linear-gradient(#4b5000, #515700);
background-image: linear-gradient(#4b5000, #515700);
}

View File

@ -11,7 +11,7 @@
#newtab-scrollbox:not([page-disabled]) {
background-color: rgb(229,229,229);
background-image: url(chrome://browser/skin/newtab/noise.png),
-moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
background-attachment: fixed;
}

View File

@ -150,7 +150,7 @@ richlistitem[type="download"][state="1"]:hover {
border-top: 1px solid hsla(0,0%,100%,.2);
border-bottom: 1px solid hsla(0,0%,0%,.4);
background-color: Highlight;
background-image: -moz-linear-gradient(hsl(210,100%,50%), hsl(210,96%,41%));
background-image: linear-gradient(hsl(210,100%,50%), hsl(210,96%,41%));
color: HighlightText;
cursor: pointer;
}
@ -303,7 +303,7 @@ richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloa
-moz-appearance: none;
min-width: 0;
min-height: 0;
background-image: -moz-linear-gradient(#505050, #575757);
background-image: linear-gradient(#505050, #575757);
border: 1px solid;
border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
-moz-border-start: none;
@ -315,5 +315,5 @@ richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloa
}
#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
background-image: -moz-linear-gradient(#4b5000, #515700);
background-image: linear-gradient(#4b5000, #515700);
}

View File

@ -11,7 +11,7 @@
#newtab-scrollbox:not([page-disabled]) {
background-color: rgb(229,229,229);
background-image: url(chrome://browser/skin/newtab/noise.png),
-moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
background-attachment: fixed;
}

View File

@ -202,3 +202,71 @@ treechildren::-moz-tree-image(cutting) {
treechildren::-moz-tree-cell-text(cutting) {
opacity: 0.7;
}
/** Downloads View **/
richlistitem.download {
height: 7em;
margin: 0;
padding: 8px;
-moz-padding-end: 0;
}
richlistitem.download:first-child {
border-top: 1px solid transparent;
}
richlistitem.download:last-child {
border-bottom: 1px solid transparent;
}
.downloadTypeIcon {
-moz-margin-end: 8px;
/* Prevent flickering when changing states. */
min-height: 32px;
min-width: 32px;
}
.blockedIcon {
list-style-image: url("chrome://global/skin/icons/Error.png");
}
.downloadTarget {
margin-bottom: 6px;
cursor: inherit;
}
.downloadDetails {
opacity: 0.7;
font-size: 95%;
cursor: inherit;
}
.downloadButton {
-moz-appearance: none;
min-width: 0;
min-height: 0;
margin: 3px;
border: none;
padding: 5px;
list-style-image: url("chrome://browser/skin/downloads/buttons.png");
}
.downloadButton > .button-box {
padding: 0;
}
/*** Button icons ***/
.downloadButton.downloadCancel {
-moz-image-region: rect(0px, 16px, 16px, 0px);
}
.downloadButton.downloadShow {
-moz-image-region: rect(16px, 16px, 32px, 0px);
}
.downloadButton.downloadRetry {
-moz-image-region: rect(32px, 16px, 48px, 0px);
}

View File

@ -16,7 +16,7 @@
border: 1px solid hsl(213,45%,65%);
box-shadow: 0 0 0 1px hsla(0,0%,100%,.5) inset,
0 1px 0 hsla(0,0%,100%,.3) inset;
background-image: -moz-linear-gradient(hsl(212,86%,92%), hsl(212,91%,86%));
background-image: linear-gradient(hsl(212,86%,92%), hsl(212,91%,86%));
color: black;
}
}

View File

@ -303,7 +303,7 @@ richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloa
-moz-appearance: none;
min-width: 0;
min-height: 0;
background-image: -moz-linear-gradient(#505050, #575757);
background-image: linear-gradient(#505050, #575757);
border: 1px solid;
border-color: hsla(0,0%,0%,.6) hsla(0,0%,0%,.4) hsla(0,0%,0%,.4);
-moz-border-start: none;
@ -315,5 +315,5 @@ richlistitem[type="download"][state="1"]:hover > stack > .downloadButton.downloa
}
#downloads-indicator[paused] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-progress > .progress-remainder {
background-image: -moz-linear-gradient(#4b5000, #515700);
background-image: linear-gradient(#4b5000, #515700);
}

View File

@ -11,7 +11,7 @@
#newtab-scrollbox:not([page-disabled]) {
background-color: rgb(229,229,229);
background-image: url(chrome://browser/skin/newtab/noise.png),
-moz-linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.2));
background-attachment: fixed;
}

View File

@ -49,6 +49,7 @@ xpcshell-tests:
--testing-modules-dir=$(DEPTH)/_tests/modules \
--xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
--xunit-suite-name=xpcshell \
--test-plugin-path=$(DIST)/plugins \
$(EXTRA_TEST_ARGS) \
$(LIBXUL_DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
@ -83,6 +84,7 @@ check-interactive:
--test-path=$(SOLO_FILE) \
--testing-modules-dir=$(DEPTH)/_tests/modules \
--profile-name=$(MOZ_APP_NAME) \
--test-plugin-path=$(DIST)/plugins \
--interactive \
$(LIBXUL_DIST)/bin/xpcshell \
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
@ -98,6 +100,7 @@ check-one:
--test-path=$(SOLO_FILE) \
--testing-modules-dir=$(DEPTH)/_tests/modules \
--profile-name=$(MOZ_APP_NAME) \
--test-plugin-path=$(DIST)/plugins \
--verbose \
$(EXTRA_TEST_ARGS) \
$(LIBXUL_DIST)/bin/xpcshell \

View File

@ -0,0 +1,15 @@
<head dir=auto id=test1><ul id=test2>
7. If no matching font face is within the "font-family" being processed by steps
</ul>
<h2 id=test3><p id=test5>* XHB7R%[+z^NvLp5 n$C
<p id=test4>
<script>
var docElement = document.body;
document.addEventListener("DOMContentLoaded", CFcrash, false);
function CFcrash() {
setTimeout('try { test5.appendChild(test4); } catch(e) {}', 50);
try { test4.parentNode.removeChild(test4); test4 = test1; } catch(e) {}
try { test4.insertBefore(test2, test4.firstChils); } catch(e) { }
try { test2.textContent = test3.textContent; } catch(e) {}
}</script>>

View File

@ -0,0 +1,14 @@
>><address id=test1> A,*/^㰞﷑ dq豑><script>
function initCF() {
try { test2 = document.createElementNS("http://www.w3.org/1999/xhtml", "tt"); } catch(e) {}
try { test2.setAttribute("dir", "auto"); } catch(e) {}
setTimeout("CFcrash()", 253);
}
document.addEventListener("DOMContentLoaded", initCF, false);
function editFuzz() {
}
function CFcrash() {
try { test2.appendChild(test1); } catch(e) {}
setTimeout('try { test2.setAttribute("dir", "&locale.dir;"); } catch(e) {}', 462);
try { test1.innerHTML = "Z3 ᜃ 洿G0겨=#⨝ g B md^뛳 j # 鮪 8媾䝀 &#x30054;ᖾd煏됚M:㕑,i⼷ Geኔ ≴핛 "; } catch(e) {}
}</script>>

View File

@ -116,4 +116,6 @@ load 752226-2.html
HTTP(..) load xhr_abortinprogress.html
load 786854.html
load xhr_empty_datauri.html
load 815477.html
load 815500.html
load 816253.html

View File

@ -45,6 +45,7 @@
#include "nsISMILAttr.h"
#include "nsClientRect.h"
#include "nsIDOMDOMTokenList.h"
#include "nsEvent.h"
class nsIDOMEventListener;
class nsIFrame;
@ -722,12 +723,15 @@ public:
* through the full dispatching of the presshell of the aPresContext; if it's
* false the event will be dispatched only as a DOM event.
* If aPresContext is nullptr, this does nothing.
*
* @param aFlags Extra flags for the dispatching event. The true flags
* will be respected.
*/
static nsresult DispatchClickEvent(nsPresContext* aPresContext,
nsInputEvent* aSourceEvent,
nsIContent* aTarget,
bool aFullDispatch,
uint32_t aFlags,
const mozilla::widget::EventFlags* aFlags,
nsEventStatus* aStatus);
/**

View File

@ -40,6 +40,7 @@ nsDOMFile.h \
nsLineBreaker.h \
nsReferencedElement.h \
nsTreeSanitizer.h \
nsViewportInfo.h \
nsXMLNameSpaceMap.h \
nsHostObjectProtocolHandler.h \
$(NULL)

View File

@ -101,6 +101,8 @@ class nsPIDOMWindow;
class nsIDocumentLoaderFactory;
class nsIDOMHTMLInputElement;
class nsViewportInfo;
namespace mozilla {
class Selection;
@ -130,40 +132,6 @@ enum EventNameType {
EventNameType_All = 0xFFFF
};
/**
* Information retrieved from the <meta name="viewport"> tag. See
* GetViewportInfo for more information on this functionality.
*/
struct ViewportInfo
{
// Default zoom indicates the level at which the display is 'zoomed in'
// initially for the user, upon loading of the page.
double defaultZoom;
// The minimum zoom level permitted by the page.
double minZoom;
// The maximum zoom level permitted by the page.
double maxZoom;
// The width of the viewport, specified by the <meta name="viewport"> tag,
// in CSS pixels.
uint32_t width;
// The height of the viewport, specified by the <meta name="viewport"> tag,
// in CSS pixels.
uint32_t height;
// Whether or not we should automatically size the viewport to the device's
// width. This is true if the document has been optimized for mobile, and
// the width property of a specified <meta name="viewport"> tag is either
// not specified, or is set to the special value 'device-width'.
bool autoSize;
// Whether or not the user can zoom in and out on the page. Default is true.
bool allowZoom;
};
struct EventNameMapping
{
nsIAtom* mAtom;
@ -1549,16 +1517,9 @@ public:
* NOTE: If the site is optimized for mobile (via the doctype), this
* will return viewport information that specifies default information.
*/
static ViewportInfo GetViewportInfo(nsIDocument* aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight);
/**
* Constrain the viewport calculations from the GetViewportInfo() function
* in order to always return sane minimum/maximum values. This modifies the
* ViewportInfo struct passed as an input parameter, in place.
*/
static void ConstrainViewportValues(ViewportInfo& aViewInfo);
static nsViewportInfo GetViewportInfo(nsIDocument* aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight);
/**
* The device-pixel-to-CSS-px ratio used to adjust meta viewport values.

View File

@ -79,8 +79,8 @@ class Element;
} // namespace mozilla
#define NS_IDOCUMENT_IID \
{ 0xcb362f1b, 0x8a05, 0x4d4f, \
{ 0x90, 0x63, 0xf2, 0x5f, 0x8b, 0x8c, 0xb2, 0xe1 } }
{ 0x1517f31a, 0x0ef9, 0x4629, \
{ 0xb4, 0x7f, 0x56, 0x31, 0x0d, 0x80, 0x61, 0xaf } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -1685,9 +1685,7 @@ public:
#undef DEPRECATED_OPERATION
void WarnOnceAbout(DeprecatedOperations aOperation, bool asError = false);
// This method may fire a DOM event; if it does so it will happen
// synchronously if aFireEventSync is true, asynchronously otherwise.
virtual void UpdateVisibilityState(bool aFireEventSync) = 0;
virtual void PostVisibilityUpdateEvent() = 0;
bool IsSyntheticDocument() { return mIsSyntheticDocument; }

View File

@ -0,0 +1,107 @@
/* 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/. */
#ifndef nsViewportInfo_h___
#define nsViewportInfo_h___
#include "nsContentUtils.h"
/**
* Default values for the nsViewportInfo class.
*/
static const double kViewportMinScale = 0.0;
static const double kViewportMaxScale = 10.0;
static const uint32_t kViewportMinWidth = 200;
static const uint32_t kViewportMaxWidth = 10000;
static const uint32_t kViewportMinHeight = 223;
static const uint32_t kViewportMaxHeight = 10000;
static const int32_t kViewportDefaultScreenWidth = 980;
/**
* Information retrieved from the <meta name="viewport"> tag. See
* nsContentUtils::GetViewportInfo for more information on this functionality.
*/
class NS_STACK_CLASS nsViewportInfo
{
public:
nsViewportInfo(uint32_t aDisplayWidth, uint32_t aDisplayHeight) :
mDefaultZoom(1.0),
mMinZoom(kViewportMinScale),
mMaxZoom(kViewportMaxScale),
mWidth(aDisplayWidth),
mHeight(aDisplayHeight),
mAutoSize(true),
mAllowZoom(true)
{
ConstrainViewportValues();
}
nsViewportInfo(double aDefaultZoom,
double aMinZoom,
double aMaxZoom,
uint32_t aWidth,
uint32_t aHeight,
bool aAutoSize,
bool aAllowZoom) :
mDefaultZoom(aDefaultZoom),
mMinZoom(aMinZoom),
mMaxZoom(aMaxZoom),
mWidth(aWidth),
mHeight(aHeight),
mAutoSize(aAutoSize),
mAllowZoom(aAllowZoom)
{
ConstrainViewportValues();
}
double GetDefaultZoom() { return mDefaultZoom; }
void SetDefaultZoom(const double aDefaultZoom);
double GetMinZoom() { return mMinZoom; }
double GetMaxZoom() { return mMaxZoom; }
uint32_t GetWidth() { return mWidth; }
uint32_t GetHeight() { return mHeight; }
bool IsAutoSizeEnabled() { return mAutoSize; }
bool IsZoomAllowed() { return mAllowZoom; }
private:
/**
* Constrain the viewport calculations from the
* nsContentUtils::GetViewportInfo() function in order to always return
* sane minimum/maximum values.
*/
void ConstrainViewportValues();
// Default zoom indicates the level at which the display is 'zoomed in'
// initially for the user, upon loading of the page.
double mDefaultZoom;
// The minimum zoom level permitted by the page.
double mMinZoom;
// The maximum zoom level permitted by the page.
double mMaxZoom;
// The width of the viewport, specified by the <meta name="viewport"> tag,
// in CSS pixels.
uint32_t mWidth;
// The height of the viewport, specified by the <meta name="viewport"> tag,
// in CSS pixels.
uint32_t mHeight;
// Whether or not we should automatically size the viewport to the device's
// width. This is true if the document has been optimized for mobile, and
// the width property of a specified <meta name="viewport"> tag is either
// not specified, or is set to the special value 'device-width'.
bool mAutoSize;
// Whether or not the user can zoom in and out on the page. Default is true.
bool mAllowZoom;
};
#endif

View File

@ -1243,7 +1243,7 @@ CSPSource.prototype = {
if (!aSource) return false;
if (!(aSource instanceof CSPSource))
return this.permits(CSPSource.create(aSource, this._CSPRep));
aSource = CSPSource.create(aSource, this._CSPRep);
// verify scheme
if (this.scheme != aSource.scheme)
@ -1469,7 +1469,7 @@ CSPHost.prototype = {
if (!(aHost instanceof CSPHost)) {
// -- compare CSPHost to String
return this.permits(CSPHost.fromString(aHost));
aHost = CSPHost.fromString(aHost);
}
var thislen = this._segments.length;
var thatlen = aHost._segments.length;

View File

@ -490,6 +490,9 @@ private:
startAfterNode);
if (textNode) {
nsTextNodeDirectionalityMap::AddEntryToMap(textNode, rootNode);
} else {
rootNode->ClearHasDirAutoSet();
rootNode->UnsetProperty(nsGkAtoms::dirAutoSetBy);
}
return PL_DHASH_REMOVE;
}

View File

@ -10,7 +10,7 @@
* utility methods for subclasses, and so forth.
*/
#include "mozilla/Util.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/Element.h"
@ -1588,14 +1588,14 @@ Element::DispatchClickEvent(nsPresContext* aPresContext,
nsInputEvent* aSourceEvent,
nsIContent* aTarget,
bool aFullDispatch,
uint32_t aFlags,
const widget::EventFlags* aExtraEventFlags,
nsEventStatus* aStatus)
{
NS_PRECONDITION(aTarget, "Must have target");
NS_PRECONDITION(aSourceEvent, "Must have source event");
NS_PRECONDITION(aStatus, "Null out param?");
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aSourceEvent), NS_MOUSE_CLICK,
nsMouseEvent event(aSourceEvent->mFlags.mIsTrusted, NS_MOUSE_CLICK,
aSourceEvent->widget, nsMouseEvent::eReal);
event.refPoint = aSourceEvent->refPoint;
uint32_t clickCount = 1;
@ -1612,7 +1612,10 @@ Element::DispatchClickEvent(nsPresContext* aPresContext,
event.clickCount = clickCount;
event.inputSource = inputSource;
event.modifiers = aSourceEvent->modifiers;
event.flags |= aFlags; // Be careful not to overwrite existing flags!
if (aExtraEventFlags) {
// Be careful not to overwrite existing flags!
event.mFlags |= *aExtraEventFlags;
}
return DispatchEvent(aPresContext, &event, aTarget, aFullDispatch, aStatus);
}
@ -2311,12 +2314,12 @@ Element::CheckHandleEventForLinksPrecondition(nsEventChainVisitor& aVisitor,
nsIURI** aURI) const
{
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
(!NS_IS_TRUSTED_EVENT(aVisitor.mEvent) &&
(!aVisitor.mEvent->mFlags.mIsTrusted &&
(aVisitor.mEvent->message != NS_MOUSE_CLICK) &&
(aVisitor.mEvent->message != NS_KEY_PRESS) &&
(aVisitor.mEvent->message != NS_UI_ACTIVATE)) ||
!aVisitor.mPresContext ||
(aVisitor.mEvent->flags & NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS)) {
aVisitor.mEvent->mFlags.mMultipleActionsPrevented) {
return false;
}
@ -2362,7 +2365,7 @@ Element::PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor)
nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
false, true, true);
// Make sure any ancestor links don't also TriggerLink
aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
}
break;
@ -2372,7 +2375,7 @@ Element::PreHandleEventForLinks(nsEventChainPreVisitor& aVisitor)
case NS_BLUR_CONTENT:
rv = LeaveLink(aVisitor.mPresContext);
if (NS_SUCCEEDED(rv)) {
aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
}
break;
@ -2420,7 +2423,7 @@ Element::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
if (handler && document) {
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_MULTIPLE_ACTIONS;
aVisitor.mEvent->mFlags.mMultipleActionsPrevented = true;
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(this);
fm->SetFocus(elem, nsIFocusManager::FLAG_BYMOUSE |
nsIFocusManager::FLAG_NOSCROLL);
@ -2446,7 +2449,7 @@ Element::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
if (shell) {
// single-click
nsEventStatus status = nsEventStatus_eIgnore;
nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
nsUIEvent actEvent(aVisitor.mEvent->mFlags.mIsTrusted,
NS_UI_ACTIVATE, 1);
rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
@ -2463,7 +2466,8 @@ Element::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
nsAutoString target;
GetLinkTarget(target);
nsContentUtils::TriggerLink(this, aVisitor.mPresContext, absURI, target,
true, true, NS_IS_TRUSTED_EVENT(aVisitor.mEvent));
true, true,
aVisitor.mEvent->mFlags.mIsTrusted);
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
}
}
@ -2476,7 +2480,7 @@ Element::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
if (keyEvent->keyCode == NS_VK_RETURN) {
nsEventStatus status = nsEventStatus_eIgnore;
rv = DispatchClickEvent(aVisitor.mPresContext, keyEvent, this,
false, 0, &status);
false, nullptr, &status);
if (NS_SUCCEEDED(rv)) {
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
}

View File

@ -120,6 +120,7 @@ CPPSRCS = \
nsTraversal.cpp \
nsTreeSanitizer.cpp \
nsTreeWalker.cpp \
nsViewportInfo.cpp \
WebSocket.cpp \
nsXHTMLContentSerializer.cpp \
nsXMLContentSerializer.cpp \
@ -161,7 +162,6 @@ FORCE_STATIC_LIB = 1
EXTRA_COMPONENTS = \
$(srcdir)/nsBadCertHandler.js \
nsBadCertHandler.manifest \
contentSecurityPolicy.js \
contentSecurityPolicy.manifest \
contentAreaDropListener.js \
contentAreaDropListener.manifest \
@ -169,6 +169,10 @@ EXTRA_COMPONENTS = \
messageWakeupService.manifest \
$(NULL)
EXTRA_PP_COMPONENTS = \
contentSecurityPolicy.js \
$(NULL)
EXTRA_JS_MODULES = \
CSPUtils.jsm \
$(NULL)

View File

@ -42,6 +42,8 @@ function ContentSecurityPolicy() {
this._referrer = "";
this._docRequest = null;
CSPdebug("CSP POLICY INITED TO 'default-src *'");
this._cache = { };
}
/*
@ -224,6 +226,7 @@ ContentSecurityPolicy.prototype = {
// (3) Save the result
this._policy = intersect;
this._isInitialized = true;
this._cache = {};
},
/**
@ -422,16 +425,17 @@ ContentSecurityPolicy.prototype = {
aContext,
aMimeTypeGuess,
aOriginalUri) {
// don't filter chrome stuff
if (aContentLocation.scheme === 'chrome' ||
aContentLocation.scheme === 'resource') {
return Ci.nsIContentPolicy.ACCEPT;
let key = aContentLocation.spec + "!" + aContentType;
if (this._cache[key]) {
return this._cache[key];
}
// interpret the context, and then pass off to the decision structure
#ifndef MOZ_B2G
// Try to remove as much as possible from the hot path on b2g.
CSPdebug("shouldLoad location = " + aContentLocation.asciiSpec);
CSPdebug("shouldLoad content type = " + aContentType);
#endif
// interpret the context, and then pass off to the decision structure
var cspContext = ContentSecurityPolicy._MAPPINGS[aContentType];
// if the mapping is null, there's no policy, let it through.
@ -461,7 +465,9 @@ ContentSecurityPolicy.prototype = {
}
}
return (this._reportOnlyMode ? Ci.nsIContentPolicy.ACCEPT : res);
let ret = this._cache[key] =
(this._reportOnlyMode ? Ci.nsIContentPolicy.ACCEPT : res);
return ret;
},
shouldProcess:

View File

@ -8,6 +8,9 @@
* attribute.
*/
#include "mozilla/DebugOnly.h"
#include "mozilla/HashFunctions.h"
#include "nsAttrValue.h"
#include "nsAttrValueInlines.h"
#include "nsIAtom.h"
@ -17,7 +20,6 @@
#include "nsContentUtils.h"
#include "nsReadableUtils.h"
#include "prprf.h"
#include "mozilla/HashFunctions.h"
#include "nsHTMLCSSStyleSheet.h"
#include "nsCSSParser.h"
#include "nsStyledElement.h"

View File

@ -78,6 +78,32 @@ CSPService::ShouldLoad(uint32_t aContentType,
if (!sCSPEnabled)
return NS_OK;
// shortcut for about: chrome: and resource: and javascript: uris since
// they're not subject to CSP content policy checks.
bool schemeMatch = false;
NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("about", &schemeMatch), NS_OK);
if (schemeMatch)
return NS_OK;
NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("chrome", &schemeMatch), NS_OK);
if (schemeMatch)
return NS_OK;
NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("resource", &schemeMatch), NS_OK);
if (schemeMatch)
return NS_OK;
NS_ENSURE_SUCCESS(aContentLocation->SchemeIs("javascript", &schemeMatch), NS_OK);
if (schemeMatch)
return NS_OK;
// These content types are not subject to CSP content policy checks:
// TYPE_CSP_REPORT, TYPE_REFRESH, TYPE_DOCUMENT
// (their mappings are null in contentSecurityPolicy.js)
if (aContentType == nsIContentPolicy::TYPE_CSP_REPORT ||
aContentType == nsIContentPolicy::TYPE_REFRESH ||
aContentType == nsIContentPolicy::TYPE_DOCUMENT) {
return NS_OK;
}
// find the principal of the document that initiated this request and see
// if it has a CSP policy object
nsCOMPtr<nsINode> node(do_QueryInterface(aRequestContext));

View File

@ -6,6 +6,7 @@
/* A namespace class for static layout utilities. */
#include "mozilla/DebugOnly.h"
#include "mozilla/Util.h"
#include "mozilla/Likely.h"
@ -168,6 +169,7 @@
#include "DecoderTraits.h"
#include "nsWrapperCacheInlines.h"
#include "nsViewportInfo.h"
extern "C" int MOZ_XMLTranslateEntity(const char* ptr, const char* end,
const char** next, PRUnichar* result);
@ -240,17 +242,6 @@ bool nsContentUtils::sFragmentParsingActive = false;
namespace {
/**
* Default values for the ViewportInfo structure.
*/
static const double kViewportMinScale = 0.0;
static const double kViewportMaxScale = 10.0;
static const uint32_t kViewportMinWidth = 200;
static const uint32_t kViewportMaxWidth = 10000;
static const uint32_t kViewportMinHeight = 223;
static const uint32_t kViewportMaxHeight = 10000;
static const int32_t kViewportDefaultScreenWidth = 980;
static const char kJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
@ -5037,32 +5028,11 @@ static void ProcessViewportToken(nsIDocument *aDocument,
(c == '\t') || (c == '\n') || (c == '\r'))
/* static */
void
nsContentUtils::ConstrainViewportValues(ViewportInfo& aViewInfo)
{
// Constrain the min/max zoom as specified at:
// dev.w3.org/csswg/css-device-adapt section 6.2
aViewInfo.maxZoom = NS_MAX(aViewInfo.minZoom, aViewInfo.maxZoom);
aViewInfo.defaultZoom = NS_MIN(aViewInfo.defaultZoom, aViewInfo.maxZoom);
aViewInfo.defaultZoom = NS_MAX(aViewInfo.defaultZoom, aViewInfo.minZoom);
}
/* static */
ViewportInfo
nsViewportInfo
nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight)
{
ViewportInfo ret;
ret.defaultZoom = 1.0;
ret.autoSize = true;
ret.allowZoom = true;
ret.width = aDisplayWidth;
ret.height = aDisplayHeight;
ret.minZoom = kViewportMinScale;
ret.maxZoom = kViewportMaxScale;
nsAutoString viewport;
aDocument->GetHeaderData(nsGkAtoms::viewport, viewport);
if (viewport.IsEmpty()) {
@ -5079,7 +5049,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
(docId.Find("Mobile") != -1) ||
(docId.Find("WML") != -1))
{
nsContentUtils::ConstrainViewportValues(ret);
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
return ret;
}
}
@ -5088,7 +5058,7 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
nsAutoString handheldFriendly;
aDocument->GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
if (handheldFriendly.EqualsLiteral("true")) {
nsContentUtils::ConstrainViewportValues(ret);
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
return ret;
}
}
@ -5218,15 +5188,8 @@ nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
allowZoom = false;
}
ret.allowZoom = allowZoom;
ret.width = width;
ret.height = height;
ret.defaultZoom = scaleFloat;
ret.minZoom = scaleMinFloat;
ret.maxZoom = scaleMaxFloat;
ret.autoSize = autoSize;
nsContentUtils::ConstrainViewportValues(ret);
nsViewportInfo ret(scaleFloat, scaleMinFloat, scaleMaxFloat, width, height,
autoSize, allowZoom);
return ret;
}
@ -5338,7 +5301,7 @@ nsContentUtils::GetDragSession()
nsresult
nsContentUtils::SetDataTransferInEvent(nsDragEvent* aDragEvent)
{
if (aDragEvent->dataTransfer || !NS_IS_TRUSTED_EVENT(aDragEvent))
if (aDragEvent->dataTransfer || !aDragEvent->mFlags.mIsTrusted)
return NS_OK;
// For draggesture and dragstart events, the data transfer object is

View File

@ -191,15 +191,15 @@ nsDOMMultipartFile::InitBlob(JSContext* aCx,
if (!d.Init(aCx, nullptr, aArgv[1])) {
return NS_ERROR_TYPE_ERR;
}
mContentType = d.type;
nativeEOL = d.endings == EndingTypesValues::Native;
mContentType = d.mType;
nativeEOL = d.mEndings == EndingTypesValues::Native;
} else {
BlobPropertyBagWorkers d;
if (!d.Init(aCx, nullptr, aArgv[1])) {
return NS_ERROR_TYPE_ERR;
}
mContentType = d.type;
nativeEOL = d.endings == EndingTypesValues::Native;
mContentType = d.mType;
nativeEOL = d.mEndings == EndingTypesValues::Native;
}
}
@ -286,9 +286,9 @@ nsDOMMultipartFile::InitFile(JSContext* aCx,
if (!d.Init(aCx, nullptr, aArgv[1])) {
return NS_ERROR_TYPE_ERR;
}
mName = d.name;
mContentType = d.type;
nativeEOL = d.endings == EndingTypesValues::Native;
mName = d.mName;
mContentType = d.mType;
nativeEOL = d.mEndings == EndingTypesValues::Native;
}
// We expect to get a path to represent as a File object,

View File

@ -7,8 +7,6 @@
#include "nsDOMMutationObserver.h"
#include "nsDOMClassInfoID.h"
#include "nsError.h"
#include "nsIClassInfo.h"
#include "nsIXPCScriptable.h"
#include "nsIScriptGlobalObject.h"
#include "nsContentUtils.h"
#include "nsThreadUtils.h"
@ -16,41 +14,62 @@
#include "nsTextFragment.h"
#include "jsapi.h"
#include "nsServiceManagerUtils.h"
#include "DictionaryHelpers.h"
nsCOMArray<nsIDOMMutationObserver>*
nsTArray<nsRefPtr<nsDOMMutationObserver> >*
nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
nsIDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
uint32_t nsDOMMutationObserver::sMutationLevel = 0;
uint64_t nsDOMMutationObserver::sCount = 0;
nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>*
nsAutoTArray<nsTArray<nsRefPtr<nsDOMMutationObserver> >, 4>*
nsDOMMutationObserver::sCurrentlyHandlingObservers = nullptr;
nsINodeList*
nsDOMMutationRecord::AddedNodes()
{
if (!mAddedNodes) {
mAddedNodes = new nsSimpleContentList(mTarget);
}
return mAddedNodes;
}
nsINodeList*
nsDOMMutationRecord::RemovedNodes()
{
if (!mRemovedNodes) {
mRemovedNodes = new nsSimpleContentList(mTarget);
}
return mRemovedNodes;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationRecord)
DOMCI_DATA(MutationRecord, nsDOMMutationRecord)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationRecord)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIDOMMutationRecord)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MutationRecord)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationRecord)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationRecord)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMMutationRecord)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationRecord)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPreviousSibling)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNextSibling)
tmp->mAddedNodes = nullptr;
tmp->mRemovedNodes = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationRecord)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPreviousSibling)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNextSibling)
@ -58,80 +77,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationRecord)
cb.NoteXPCOMChild(static_cast<nsIDOMNodeList*>(tmp->mAddedNodes));
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mRemovedNodes");
cb.NoteXPCOMChild(static_cast<nsIDOMNodeList*>(tmp->mRemovedNodes));
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMETHODIMP
nsDOMMutationRecord::GetType(nsAString& aType)
{
aType = mType;
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetTarget(nsIDOMNode** aTarget)
{
nsCOMPtr<nsIDOMNode> n = do_QueryInterface(mTarget);
n.forget(aTarget);
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetAddedNodes(nsIDOMNodeList** aAddedNodes)
{
if (!mAddedNodes && mTarget) {
mAddedNodes = new nsSimpleContentList(mTarget);
}
NS_IF_ADDREF(*aAddedNodes = mAddedNodes);
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetRemovedNodes(nsIDOMNodeList** aRemovedNodes)
{
if (!mRemovedNodes && mTarget) {
mRemovedNodes = new nsSimpleContentList(mTarget);
}
NS_IF_ADDREF(*aRemovedNodes = mRemovedNodes);
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetPreviousSibling(nsIDOMNode** aPreviousSibling)
{
nsCOMPtr<nsIDOMNode> n = do_QueryInterface(mPreviousSibling);
*aPreviousSibling = n.forget().get();
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetNextSibling(nsIDOMNode** aNextSibling)
{
nsCOMPtr<nsIDOMNode> n = do_QueryInterface(mNextSibling);
*aNextSibling = n.forget().get();
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetAttributeName(nsAString& aAttrName)
{
aAttrName = mAttrName;
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetAttributeNamespace(nsAString& aAttrNamespace)
{
aAttrNamespace = mAttrNamespace;
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationRecord::GetOldValue(nsAString& aPrevValue)
{
aPrevValue = mPrevValue;
return NS_OK;
}
// Observer
NS_IMPL_ADDREF(nsMutationReceiver)
@ -143,6 +91,13 @@ NS_INTERFACE_MAP_BEGIN(nsMutationReceiver)
NS_INTERFACE_MAP_ENTRY(nsMutationReceiver)
NS_INTERFACE_MAP_END
nsMutationReceiver::nsMutationReceiver(nsINode* aTarget,
nsDOMMutationObserver* aObserver)
: nsMutationReceiverBase(aTarget, aObserver)
{
mTarget->BindObject(aObserver);
}
void
nsMutationReceiver::Disconnect(bool aRemoveFromObserver)
{
@ -154,7 +109,7 @@ nsMutationReceiver::Disconnect(bool aRemoveFromObserver)
mParent = nullptr;
nsINode* target = mTarget;
mTarget = nullptr;
nsIDOMMutationObserver* observer = mObserver;
nsDOMMutationObserver* observer = mObserver;
mObserver = nullptr;
RemoveClones();
@ -387,14 +342,9 @@ void nsMutationReceiver::NodeWillBeDestroyed(const nsINode *aNode)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationObserver)
DOMCI_DATA(MutationObserver, nsDOMMutationObserver)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationObserver)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMutationObserver)
NS_INTERFACE_MAP_ENTRY(nsIDOMMutationObserver)
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MutationObserver)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationObserver)
@ -406,7 +356,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationObserver)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK(mScriptContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
for (int32_t i = 0; i < tmp->mReceivers.Count(); ++i) {
tmp->mReceivers[i]->Disconnect(false);
@ -419,7 +368,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMutationObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMutationObserver)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScriptContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReceivers)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingMutations)
@ -505,59 +453,72 @@ void
nsDOMMutationObserver::RescheduleForRun()
{
if (!sScheduledMutationObservers) {
sScheduledMutationObservers = new nsCOMArray<nsIDOMMutationObserver>;
sScheduledMutationObservers = new nsTArray<nsRefPtr<nsDOMMutationObserver> >;
}
bool didInsert = false;
for (int32_t i = 0; i < sScheduledMutationObservers->Count(); ++i) {
for (uint32_t i = 0; i < sScheduledMutationObservers->Length(); ++i) {
if (static_cast<nsDOMMutationObserver*>((*sScheduledMutationObservers)[i])
->mId > mId) {
sScheduledMutationObservers->InsertObjectAt(this, i);
sScheduledMutationObservers->InsertElementAt(i, this);
didInsert = true;
break;
}
}
if (!didInsert) {
sScheduledMutationObservers->AppendObject(this);
sScheduledMutationObservers->AppendElement(this);
}
}
NS_IMETHODIMP
nsDOMMutationObserver::Observe(nsIDOMNode* aTarget,
const JS::Value& aOptions,
JSContext* aCx)
void
nsDOMMutationObserver::Observe(nsINode& aTarget,
const mozilla::dom::MutationObserverInit& aOptions,
mozilla::ErrorResult& aRv)
{
nsCOMPtr<nsINode> target = do_QueryInterface(aTarget);
NS_ENSURE_STATE(target);
mozilla::dom::MutationObserverInit d;
nsresult rv = d.Init(aCx, &aOptions);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(d.childList || d.attributes || d.characterData,
NS_ERROR_DOM_SYNTAX_ERR);
NS_ENSURE_TRUE(!d.attributeOldValue || d.attributes,
NS_ERROR_DOM_SYNTAX_ERR);
NS_ENSURE_TRUE(!d.characterDataOldValue || d.characterData,
NS_ERROR_DOM_SYNTAX_ERR);
if (!(aOptions.mChildList || aOptions.mAttributes || aOptions.mCharacterData)) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
if (aOptions.mAttributeOldValue && !aOptions.mAttributes) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
if (aOptions.mCharacterDataOldValue && !aOptions.mCharacterData) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
nsCOMArray<nsIAtom> filters;
bool allAttrs = true;
if (!d.attributeFilter.isUndefined()) {
if (aOptions.mAttributeFilter.WasPassed()) {
allAttrs = false;
rv = nsContentUtils::JSArrayToAtomArray(aCx, d.attributeFilter, filters);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(filters.Count() == 0 || d.attributes,
NS_ERROR_DOM_SYNTAX_ERR);
const mozilla::dom::Sequence<nsString>& filtersAsString =
aOptions.mAttributeFilter.Value();
uint32_t len = filtersAsString.Length();
if (len != 0 && !aOptions.mAttributes) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
if (!filters.SetCapacity(len)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
for (uint32_t i = 0; i < len; ++i) {
nsCOMPtr<nsIAtom> a = do_GetAtom(filtersAsString[i]);
filters.AppendObject(a);
}
}
nsMutationReceiver* r = GetReceiverFor(target, true);
r->SetChildList(d.childList);
r->SetAttributes(d.attributes);
r->SetCharacterData(d.characterData);
r->SetSubtree(d.subtree);
r->SetAttributeOldValue(d.attributeOldValue);
r->SetCharacterDataOldValue(d.characterDataOldValue);
nsMutationReceiver* r = GetReceiverFor(&aTarget, true);
r->SetChildList(aOptions.mChildList);
r->SetAttributes(aOptions.mAttributes);
r->SetCharacterData(aOptions.mCharacterData);
r->SetSubtree(aOptions.mSubtree);
r->SetAttributeOldValue(aOptions.mAttributeOldValue);
r->SetCharacterDataOldValue(aOptions.mCharacterDataOldValue);
r->SetAttributeFilter(filters);
r->SetAllAttributes(allAttrs);
r->RemoveClones();
@ -568,11 +529,9 @@ nsDOMMutationObserver::Observe(nsIDOMNode* aTarget,
"All the receivers should have a target!");
}
#endif
return NS_OK;
}
NS_IMETHODIMP
void
nsDOMMutationObserver::Disconnect()
{
for (int32_t i = 0; i < mReceivers.Count(); ++i) {
@ -581,65 +540,31 @@ nsDOMMutationObserver::Disconnect()
mReceivers.Clear();
mCurrentMutations.Clear();
mPendingMutations.Clear();
return NS_OK;
}
NS_IMETHODIMP
nsDOMMutationObserver::TakeRecords(nsIVariant** aRetVal)
void
nsDOMMutationObserver::TakeRecords(
nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal)
{
*aRetVal = TakeRecords().get();
return NS_OK;
aRetVal.Clear();
mPendingMutations.SwapElements(aRetVal);
}
already_AddRefed<nsIVariant>
nsDOMMutationObserver::TakeRecords()
// static
already_AddRefed<nsDOMMutationObserver>
nsDOMMutationObserver::Constructor(nsISupports* aGlobal,
mozilla::dom::MutationCallback& aCb,
mozilla::ErrorResult& aRv)
{
nsCOMPtr<nsIWritableVariant> mutations =
do_CreateInstance("@mozilla.org/variant;1");
int32_t len = mPendingMutations.Count();
if (len == 0) {
mutations->SetAsEmptyArray();
} else {
nsTArray<nsIDOMMutationRecord*> mods(len);
for (int32_t i = 0; i < len; ++i) {
mods.AppendElement(mPendingMutations[i]);
}
mutations->SetAsArray(nsIDataType::VTYPE_INTERFACE,
&NS_GET_IID(nsIDOMMutationRecord),
mods.Length(),
const_cast<void*>(
static_cast<const void*>(mods.Elements())));
mPendingMutations.Clear();
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal);
if (!window) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
return mutations.forget();
}
NS_IMETHODIMP
nsDOMMutationObserver::Initialize(nsISupports* aOwner, JSContext* cx,
JSObject* obj, uint32_t argc, jsval* argv)
{
mOwner = do_QueryInterface(aOwner);
if (!mOwner) {
NS_WARNING("Unexpected nsIJSNativeInitializer owner");
return NS_OK;
}
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aOwner);
NS_ENSURE_STATE(sgo);
mScriptContext = sgo->GetContext();
NS_ENSURE_STATE(mScriptContext);
NS_ENSURE_STATE(argc >= 1);
NS_ENSURE_STATE(!JSVAL_IS_PRIMITIVE(argv[0]));
nsCOMPtr<nsISupports> tmp;
nsContentUtils::XPConnect()->WrapJS(cx, JSVAL_TO_OBJECT(argv[0]),
NS_GET_IID(nsIMutationObserverCallback),
getter_AddRefs(tmp));
mCallback = do_QueryInterface(tmp);
NS_ENSURE_STATE(mCallback);
return NS_OK;
MOZ_ASSERT(window->IsInnerWindow());
nsRefPtr<nsDOMMutationObserver> observer =
new nsDOMMutationObserver(window.forget(), aCb);
return observer.forget();
}
void
@ -657,23 +582,23 @@ nsDOMMutationObserver::HandleMutation()
mTransientReceivers.Clear();
nsPIDOMWindow* outer = mOwner->GetOuterWindow();
if (!mPendingMutations.Count() || !outer ||
if (!mPendingMutations.Length() || !outer ||
outer->GetCurrentInnerWindow() != mOwner) {
mPendingMutations.Clear();
return;
}
nsCxPusher pusher;
nsCOMPtr<nsIDOMEventTarget> et = do_QueryInterface(mOwner);
if (!mCallback || !pusher.Push(et)) {
mPendingMutations.Clear();
return;
}
nsCOMPtr<nsIVariant> mutations = TakeRecords();
nsAutoMicroTask mt;
sCurrentObserver = this; // For 'this' handling.
mCallback->HandleMutations(mutations, this);
sCurrentObserver = nullptr;
nsTArray<nsRefPtr<nsDOMMutationRecord> > mutationsArray;
TakeRecords(mutationsArray);
mozilla::dom::Sequence<mozilla::dom::OwningNonNull<nsDOMMutationRecord> >
mutations;
uint32_t len = mutationsArray.Length();
NS_ENSURE_TRUE_VOID(mutations.SetCapacity(len));
for (uint32_t i = 0; i < len; ++i) {
*mutations.AppendElement() = mutationsArray[i].forget();
}
mozilla::ErrorResult rv;
mCallback->Call(this, mutations, *this, rv);
}
class AsyncMutationHandler : public nsRunnable
@ -704,21 +629,21 @@ nsDOMMutationObserver::HandleMutationsInternal()
return;
}
nsCOMArray<nsIDOMMutationObserver>* suppressedObservers = nullptr;
nsTArray<nsRefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
while (sScheduledMutationObservers) {
nsCOMArray<nsIDOMMutationObserver>* observers = sScheduledMutationObservers;
nsTArray<nsRefPtr<nsDOMMutationObserver> >* observers = sScheduledMutationObservers;
sScheduledMutationObservers = nullptr;
for (int32_t i = 0; i < observers->Count(); ++i) {
for (uint32_t i = 0; i < observers->Length(); ++i) {
sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
if (!sCurrentObserver->Suppressed()) {
sCurrentObserver->HandleMutation();
} else {
if (!suppressedObservers) {
suppressedObservers = new nsCOMArray<nsIDOMMutationObserver>;
suppressedObservers = new nsTArray<nsRefPtr<nsDOMMutationObserver> >;
}
if (suppressedObservers->IndexOf(sCurrentObserver) < 0) {
suppressedObservers->AppendObject(sCurrentObserver);
if (!suppressedObservers->Contains(sCurrentObserver)) {
suppressedObservers->AppendElement(sCurrentObserver);
}
}
}
@ -726,8 +651,8 @@ nsDOMMutationObserver::HandleMutationsInternal()
}
if (suppressedObservers) {
for (int32_t i = 0; i < suppressedObservers->Count(); ++i) {
static_cast<nsDOMMutationObserver*>(suppressedObservers->ObjectAt(i))->
for (uint32_t i = 0; i < suppressedObservers->Length(); ++i) {
static_cast<nsDOMMutationObserver*>(suppressedObservers->ElementAt(i))->
RescheduleForRun();
}
delete suppressedObservers;
@ -747,9 +672,9 @@ nsDOMMutationObserver::CurrentRecord(const nsAString& aType)
uint32_t last = sMutationLevel - 1;
if (!mCurrentMutations[last]) {
nsDOMMutationRecord* r = new nsDOMMutationRecord(aType);
nsDOMMutationRecord* r = new nsDOMMutationRecord(aType, GetParentObject());
mCurrentMutations[last] = r;
mPendingMutations.AppendObject(r);
mPendingMutations.AppendElement(r);
ScheduleForRun();
}
@ -764,7 +689,7 @@ nsDOMMutationObserver::~nsDOMMutationObserver()
for (int32_t i = 0; i < mReceivers.Count(); ++i) {
mReceivers[i]->RemoveClones();
}
}
}
void
nsDOMMutationObserver::EnterMutationHandling()
@ -781,9 +706,9 @@ nsDOMMutationObserver::LeaveMutationHandling()
{
if (sCurrentlyHandlingObservers &&
sCurrentlyHandlingObservers->Length() == sMutationLevel) {
nsCOMArray<nsIDOMMutationObserver>& obs =
nsTArray<nsRefPtr<nsDOMMutationObserver> >& obs =
sCurrentlyHandlingObservers->ElementAt(sMutationLevel - 1);
for (int32_t i = 0; i < obs.Count(); ++i) {
for (uint32_t i = 0; i < obs.Length(); ++i) {
nsDOMMutationObserver* o =
static_cast<nsDOMMutationObserver*>(obs[i]);
if (o->mCurrentMutations.Length() == sMutationLevel) {
@ -803,7 +728,7 @@ nsDOMMutationObserver::AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObse
if (!sCurrentlyHandlingObservers) {
sCurrentlyHandlingObservers =
new nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>;
new nsAutoTArray<nsTArray<nsRefPtr<nsDOMMutationObserver> >, 4>;
}
while (sCurrentlyHandlingObservers->Length() < sMutationLevel) {
@ -812,8 +737,8 @@ nsDOMMutationObserver::AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObse
}
uint32_t last = sMutationLevel - 1;
if (sCurrentlyHandlingObservers->ElementAt(last).IndexOf(aObserver) < 0) {
sCurrentlyHandlingObservers->ElementAt(last).AppendObject(aObserver);
if (!sCurrentlyHandlingObservers->ElementAt(last).Contains(aObserver)) {
sCurrentlyHandlingObservers->ElementAt(last).AppendElement(aObserver);
}
}
@ -889,8 +814,9 @@ nsAutoMutationBatch::Done()
addedList->AppendElement(mAddedNodes[i]);
}
nsDOMMutationRecord* m =
new nsDOMMutationRecord(NS_LITERAL_STRING("childList"));
ob->mPendingMutations.AppendObject(m);
new nsDOMMutationRecord(NS_LITERAL_STRING("childList"),
ob->GetParentObject());
ob->mPendingMutations.AppendElement(m);
m->mTarget = mBatchTarget;
m->mRemovedNodes = removedList;
m->mAddedNodes = addedList;

View File

@ -7,9 +7,7 @@
#ifndef nsDOMMutationObserver_h
#define nsDOMMutationObserver_h
#include "nsIDOMMutationObserver.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIJSNativeInitializer.h"
#include "nsPIDOMWindow.h"
#include "nsIScriptContext.h"
#include "nsStubMutationObserver.h"
@ -23,22 +21,77 @@
#include "nsNodeUtils.h"
#include "nsIDOMMutationEvent.h"
#include "nsWrapperCache.h"
#include "mozilla/dom/MutationObserverBinding.h"
class nsDOMMutationObserver;
class nsDOMMutationRecord : public nsIDOMMutationRecord
class nsDOMMutationRecord : public nsISupports,
public nsWrapperCache
{
public:
nsDOMMutationRecord(const nsAString& aType) : mType(aType)
nsDOMMutationRecord(const nsAString& aType, nsISupports* aOwner)
: mType(aType), mOwner(aOwner)
{
mAttrName.SetIsVoid(PR_TRUE);
mAttrNamespace.SetIsVoid(PR_TRUE);
mPrevValue.SetIsVoid(PR_TRUE);
SetIsDOMBinding();
}
virtual ~nsDOMMutationRecord() {}
nsISupports* GetParentObject() const
{
return mOwner;
}
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap)
{
return mozilla::dom::MutationRecordBinding::Wrap(aCx, aScope, this,
aTriedToWrap);
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMMutationRecord)
NS_DECL_NSIDOMMUTATIONRECORD
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationRecord)
void GetType(nsString& aRetVal) const
{
aRetVal = mType;
}
nsINode* GetTarget() const
{
return mTarget;
}
nsINodeList* AddedNodes();
nsINodeList* RemovedNodes();
nsINode* GetPreviousSibling() const
{
return mPreviousSibling;
}
nsINode* GetNextSibling() const
{
return mNextSibling;
}
void GetAttributeName(nsString& aRetVal) const
{
aRetVal = mAttrName;
}
void GetAttributeNamespace(nsString& aRetVal) const
{
aRetVal = mAttrNamespace;
}
void GetOldValue(nsString& aRetVal) const
{
aRetVal = mPrevValue;
}
nsCOMPtr<nsINode> mTarget;
nsString mType;
@ -49,6 +102,7 @@ public:
nsRefPtr<nsSimpleContentList> mRemovedNodes;
nsCOMPtr<nsINode> mPreviousSibling;
nsCOMPtr<nsINode> mNextSibling;
nsCOMPtr<nsISupports> mOwner;
};
// Base class just prevents direct access to
@ -143,7 +197,7 @@ public:
}
protected:
nsMutationReceiverBase(nsINode* aTarget, nsIDOMMutationObserver* aObserver)
nsMutationReceiverBase(nsINode* aTarget, nsDOMMutationObserver* aObserver)
: mTarget(aTarget), mObserver(aObserver), mRegisterTarget(aTarget)
{
mRegisterTarget->AddMutationObserver(this);
@ -181,7 +235,7 @@ protected:
}
nsCOMArray<nsIAtom>& filters = AttributeFilter();
for (int32_t i = 0; i < filters.Count(); ++i) {
for (int32_t i = 0; i < filters.Count(); ++i) {
if (filters[i] == aAttr) {
return true;
}
@ -191,7 +245,7 @@ protected:
// The target for the MutationObserver.observe() method.
nsINode* mTarget;
nsIDOMMutationObserver* mObserver;
nsDOMMutationObserver* mObserver;
nsRefPtr<nsMutationReceiverBase> mParent; // Cleared after microtask.
// The node to which Gecko-internal nsIMutationObserver was registered to.
// This is different than mTarget when dealing with transient observers.
@ -220,11 +274,7 @@ private:
class nsMutationReceiver : public nsMutationReceiverBase
{
public:
nsMutationReceiver(nsINode* aTarget, nsIDOMMutationObserver* aObserver)
: nsMutationReceiverBase(aTarget, aObserver)
{
mTarget->BindObject(aObserver);
}
nsMutationReceiver(nsINode* aTarget, nsDOMMutationObserver* aObserver);
nsMutationReceiver(nsINode* aRegisterTarget, nsMutationReceiverBase* aParent)
: nsMutationReceiverBase(aRegisterTarget, aParent)
@ -289,52 +339,45 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsMutationReceiver, NS_MUTATION_OBSERVER_IID)
class nsDOMMutationObserver : public nsIDOMMutationObserver,
public nsIJSNativeInitializer,
class nsDOMMutationObserver : public nsISupports,
public nsWrapperCache
{
public:
nsDOMMutationObserver() : mWaitingForRun(false), mId(++sCount)
nsDOMMutationObserver(already_AddRefed<nsPIDOMWindow> aOwner,
mozilla::dom::MutationCallback& aCb)
: mOwner(aOwner), mCallback(&aCb), mWaitingForRun(false), mId(++sCount)
{
mTransientReceivers.Init();
SetIsDOMBinding();
}
virtual ~nsDOMMutationObserver();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMMutationObserver,
nsIDOMMutationObserver)
NS_DECL_NSIDOMMUTATIONOBSERVER
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMMutationObserver)
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
uint32_t argc, jsval* argv);
static already_AddRefed<nsDOMMutationObserver>
Constructor(nsISupports* aGlobal, mozilla::dom::MutationCallback& aCb,
mozilla::ErrorResult& aRv);
void GetParentObject(nsIScriptGlobalObject** aParentObject)
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap)
{
if (mOwner) {
CallQueryInterface(mOwner, aParentObject);
} else {
*aParentObject = nullptr;
}
return mozilla::dom::MutationObserverBinding::Wrap(aCx, aScope,
this, aTriedToWrap);
}
static nsDOMMutationObserver* FromSupports(nsISupports* aSupports)
nsISupports* GetParentObject() const
{
nsIDOMMutationObserver* mutationObserver =
static_cast<nsIDOMMutationObserver*>(aSupports);
#ifdef DEBUG
{
nsCOMPtr<nsIDOMMutationObserver> mutationObserver_qi =
do_QueryInterface(aSupports);
// If this assertion fires the QI implementation for the object in
// question doesn't use the nsIDOMMutationObserver pointer as the
// nsISupports pointer. That must be fixed, or we'll crash...
NS_ASSERTION(mutationObserver_qi == mutationObserver, "Uh, fix QI!");
}
#endif
return static_cast<nsDOMMutationObserver*>(mutationObserver);
return mOwner;
}
void Observe(nsINode& aTarget,
const mozilla::dom::MutationObserverInit& aOptions,
mozilla::ErrorResult& aRv);
void Disconnect();
void TakeRecords(nsTArray<nsRefPtr<nsDOMMutationRecord> >& aRetVal);
void HandleMutation();
// static methods
@ -348,11 +391,6 @@ public:
static void EnterMutationHandling();
static void LeaveMutationHandling();
static nsIDOMMutationObserver* CurrentObserver()
{
return sCurrentObserver;
}
static void Shutdown();
protected:
friend class nsMutationReceiver;
@ -383,29 +421,28 @@ protected:
static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver);
nsCOMPtr<nsIScriptContext> mScriptContext;
nsCOMPtr<nsPIDOMWindow> mOwner;
nsCOMArray<nsMutationReceiver> mReceivers;
nsClassHashtable<nsISupportsHashKey,
nsCOMArray<nsMutationReceiver> > mTransientReceivers;
nsCOMArray<nsMutationReceiver> > mTransientReceivers;
// MutationRecords which are being constructed.
nsAutoTArray<nsDOMMutationRecord*, 4> mCurrentMutations;
// MutationRecords which will be handed to the callback at the end of
// the microtask.
nsCOMArray<nsDOMMutationRecord> mPendingMutations;
nsCOMPtr<nsIMutationObserverCallback> mCallback;
nsTArray<nsRefPtr<nsDOMMutationRecord> > mPendingMutations;
nsRefPtr<mozilla::dom::MutationCallback> mCallback;
bool mWaitingForRun;
uint64_t mId;
static uint64_t sCount;
static nsCOMArray<nsIDOMMutationObserver>* sScheduledMutationObservers;
static nsIDOMMutationObserver* sCurrentObserver;
static nsTArray<nsRefPtr<nsDOMMutationObserver> >* sScheduledMutationObservers;
static nsDOMMutationObserver* sCurrentObserver;
static uint32_t sMutationLevel;
static nsAutoTArray<nsCOMArray<nsIDOMMutationObserver>, 4>*
static nsAutoTArray<nsTArray<nsRefPtr<nsDOMMutationObserver> >, 4>*
sCurrentlyHandlingObservers;
};
@ -537,12 +574,4 @@ nsMutationReceiverBase::Observer()
mParent->Observer() : static_cast<nsDOMMutationObserver*>(mObserver);
}
#define NS_DOMMUTATIONOBSERVER_CID \
{ /* b66b9490-52f7-4f2a-b998-dbb1d59bc13e */ \
0xb66b9490, 0x52f7, 0x4f2a, \
{ 0xb9, 0x98, 0xdb, 0xb1, 0xd5, 0x9b, 0xc1, 0x3e } }
#define NS_DOMMUTATIONOBSERVER_CONTRACTID \
"@mozilla.org/dommutationobserver;1"
#endif

View File

@ -8,6 +8,7 @@
* Base class for all our document implementations.
*/
#include "mozilla/DebugOnly.h"
#include "mozilla/Util.h"
#include "mozilla/Likely.h"
@ -7064,7 +7065,7 @@ nsDocument::OnPageShow(bool aPersisted,
SetImagesNeedAnimating(true);
}
UpdateVisibilityState(true);
UpdateVisibilityState();
nsCOMPtr<nsIDOMEventTarget> target = aDispatchStartTarget;
if (!target) {
@ -7126,7 +7127,7 @@ nsDocument::OnPageHide(bool aPersisted,
mVisible = false;
UpdateVisibilityState(true);
UpdateVisibilityState();
EnumerateExternalResources(NotifyPageHide, &aPersisted);
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
@ -9484,37 +9485,25 @@ nsDocument::GetMozPointerLockElement(nsIDOMElement** aPointerLockedElement)
#undef TOUCH_EVENT
#undef EVENT
/* virtual */ void
nsDocument::UpdateVisibilityState(bool aFireEventSync)
void
nsDocument::UpdateVisibilityState()
{
VisibilityState oldState = mVisibilityState;
mVisibilityState = GetVisibilityState();
if (oldState != mVisibilityState) {
if (aFireEventSync) {
FireVisibilityChangeEvent();
} else {
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &nsDocument::FireVisibilityChangeEvent);
NS_DispatchToMainThread(event);
}
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
NS_LITERAL_STRING("visibilitychange"),
/* bubbles = */ true,
/* cancelable = */ false);
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
NS_LITERAL_STRING("mozvisibilitychange"),
/* bubbles = */ true,
/* cancelable = */ false);
EnumerateFreezableElements(NotifyActivityChanged, nullptr);
}
}
void
nsDocument::FireVisibilityChangeEvent()
{
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
NS_LITERAL_STRING("visibilitychange"),
/* bubbles = */ true,
/* cancelable = */ false);
nsContentUtils::DispatchTrustedEvent(this, static_cast<nsIDocument*>(this),
NS_LITERAL_STRING("mozvisibilitychange"),
/* bubbles = */ true,
/* cancelable = */ false);
}
nsDocument::VisibilityState
nsDocument::GetVisibilityState() const
{
@ -9533,6 +9522,14 @@ nsDocument::GetVisibilityState() const
return eVisible;
}
/* virtual */ void
nsDocument::PostVisibilityUpdateEvent()
{
nsCOMPtr<nsIRunnable> event =
NS_NewRunnableMethod(this, &nsDocument::UpdateVisibilityState);
NS_DispatchToMainThread(event);
}
NS_IMETHODIMP
nsDocument::GetMozHidden(bool* aHidden)
{

View File

@ -995,8 +995,11 @@ public:
bool SetPointerLock(Element* aElement, int aCursorStyle);
static void UnlockPointer();
virtual void UpdateVisibilityState(bool aFireEventSync);
void FireVisibilityChangeEvent();
// This method may fire a DOM event; if it does so it will happen
// synchronously.
void UpdateVisibilityState();
// Posts an event to call UpdateVisibilityState
virtual void PostVisibilityUpdateEvent();
virtual void DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const;
// DocSizeOfIncludingThis is inherited from nsIDocument.

View File

@ -3,6 +3,7 @@
* 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 "mozilla/DebugOnly.h"
#include "mozilla/Util.h"
#include "nsEventSource.h"

View File

@ -8,6 +8,8 @@
* nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes.
*/
#include "mozilla/DebugOnly.h"
#include "nsGenericDOMDataNode.h"
#include "mozilla/dom/Element.h"
#include "nsIDocument.h"

View File

@ -245,7 +245,7 @@ nsPluginCrashedEvent::Run()
event->InitEvent(NS_LITERAL_STRING("PluginCrashed"), true, true);
event->SetTrusted(true);
event->GetInternalNSEvent()->flags |= NS_EVENT_FLAG_ONLY_CHROME_DISPATCH;
event->GetInternalNSEvent()->mFlags.mOnlyChromeDispatch = true;
nsCOMPtr<nsIWritableVariant> variant;
@ -1962,12 +1962,14 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
// Create the final listener if we're loading with a channel. We can't do
// this in the loading block above as it requires an instance.
if (aLoadingChannel && NS_SUCCEEDED(rv)) {
// Plugins can continue to run even if their initial stream dies. Some
// plugins will even return failure codes to reject the stream, but expect
// to continue running, so ignore the error code. rv is thus the result of
// spawning the plugin above
if (NS_SUCCEEDED(rv) && MakePluginListener()) {
mFinalListener->OnStartRequest(mChannel, nullptr);
rv = mFinalListener->OnStartRequest(mChannel, nullptr);
if (NS_FAILED(rv)) {
// Plugins can reject their initial stream, but continue to run.
CloseChannel();
NS_ENSURE_TRUE(mIsLoading, NS_OK);
rv = NS_OK;
}
}
}
} else if (finalListener) {

View File

@ -59,10 +59,8 @@ nsScriptElement::ScriptEvaluated(nsresult aResult,
nsEventStatus status = nsEventStatus_eIgnore;
uint32_t type = NS_SUCCEEDED(aResult) ? NS_LOAD : NS_LOAD_ERROR;
nsEvent event(true, type);
if (type == NS_LOAD) {
// Load event doesn't bubble.
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
}
// Load event doesn't bubble.
event.mFlags.mBubbles = (type != NS_LOAD);
nsEventDispatcher::Dispatch(cont, presContext, &event, nullptr, &status);
}

View File

@ -0,0 +1,23 @@
/* 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 "nsViewportInfo.h"
void
nsViewportInfo::SetDefaultZoom(const double aDefaultZoom)
{
MOZ_ASSERT(aDefaultZoom >= 0.0f);
mDefaultZoom = aDefaultZoom;
}
void
nsViewportInfo::ConstrainViewportValues()
{
// Constrain the min/max zoom as specified at:
// dev.w3.org/csswg/css-device-adapt section 6.2
mMaxZoom = NS_MAX(mMinZoom, mMaxZoom);
mDefaultZoom = NS_MIN(mDefaultZoom, mMaxZoom);
mDefaultZoom = NS_MAX(mDefaultZoom, mMinZoom);
}

View File

@ -371,11 +371,8 @@ nsXHREventTarget::DisconnectFromOwner()
/////////////////////////////////////////////
DOMCI_DATA(XMLHttpRequestUpload, nsXMLHttpRequestUpload)
NS_INTERFACE_MAP_BEGIN(nsXMLHttpRequestUpload)
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLHttpRequestUpload)
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
@ -633,8 +630,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mResultJSON)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
DOMCI_DATA(XMLHttpRequest, nsXMLHttpRequest)
// QueryInterface implementation for nsXMLHttpRequest
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequest)
@ -647,7 +642,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequest)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLHttpRequest)
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequest, nsXHREventTarget)
@ -2338,8 +2332,7 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult
nsEventListenerManager* manager = eventTarget->GetListenerManager(true);
manager->AddEventListenerByType(new nsXHRParseEndListener(this),
NS_LITERAL_STRING("DOMContentLoaded"),
NS_EVENT_FLAG_BUBBLE |
NS_EVENT_FLAG_SYSTEM_EVENT);
dom::TrustedEventsAtSystemGroupBubble());
return NS_OK;
}
// We might have been sent non-XML data. If that was the case,

View File

@ -159,7 +159,7 @@ public:
nsRefPtr<nsXMLHttpRequest> req = new nsXMLHttpRequest();
req->Construct(principal->GetPrincipal(), window);
req->InitParameters(aParams.mozAnon, aParams.mozSystem);
req->InitParameters(aParams.mMozAnon, aParams.mMozSystem);
return req.forget();
}

View File

@ -171,8 +171,8 @@ for (var largeLength = 0; largeLength < (0x0000FFFF + 2); ++largeLength) {
large += "A";
}
const XHR = SpecialPowers.Ci.nsIXMLHttpRequest;
const UPLOAD = SpecialPowers.Ci.nsIXMLHttpRequestUpload;
const XHR = XMLHttpRequest;
const UPLOAD = XMLHttpRequestUpload;
var tests =
[

View File

@ -525,8 +525,6 @@ NS_INTERFACE_MAP_END
// Initialize our static variables.
uint32_t CanvasRenderingContext2D::sNumLivingContexts = 0;
uint8_t (*CanvasRenderingContext2D::sUnpremultiplyTable)[256] = nullptr;
uint8_t (*CanvasRenderingContext2D::sPremultiplyTable)[256] = nullptr;
DrawTarget* CanvasRenderingContext2D::sErrorTarget = nullptr;
@ -551,10 +549,6 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
}
sNumLivingContexts--;
if (!sNumLivingContexts) {
delete[] sUnpremultiplyTable;
delete[] sPremultiplyTable;
sUnpremultiplyTable = nullptr;
sPremultiplyTable = nullptr;
NS_IF_RELEASE(sErrorTarget);
}
}
@ -2859,7 +2853,7 @@ CanvasRenderingContext2D::IsPointInPath(double x, double y)
}
bool
CanvasRenderingContext2D::MozIsPointInStroke(double x, double y)
CanvasRenderingContext2D::IsPointInStroke(double x, double y)
{
if (!FloatValidate(x,y)) {
return false;
@ -3325,33 +3319,6 @@ CanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* elem,
// device pixel getting/setting
//
void
CanvasRenderingContext2D::EnsureUnpremultiplyTable() {
if (sUnpremultiplyTable)
return;
// Infallably alloc the unpremultiply table.
sUnpremultiplyTable = new uint8_t[256][256];
// It's important that the array be indexed first by alpha and then by rgb
// value. When we unpremultiply a pixel, we're guaranteed to do three
// lookups with the same alpha; indexing by alpha first makes it likely that
// those three lookups will be close to one another in memory, thus
// increasing the chance of a cache hit.
// a == 0 case
for (uint32_t c = 0; c <= 255; c++) {
sUnpremultiplyTable[0][c] = c;
}
for (int a = 1; a <= 255; a++) {
for (int c = 0; c <= 255; c++) {
sUnpremultiplyTable[a][c] = (uint8_t)((c * 255) / a);
}
}
}
already_AddRefed<ImageData>
CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx,
double aSy, double aSw,
@ -3484,9 +3451,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
}
}
// make sure sUnpremultiplyTable has been created
EnsureUnpremultiplyTable();
// NOTE! dst is the same as src, and this relies on reading
// from src and advancing that ptr before writing to dst.
// NOTE! I'm not sure that it is, I think this comment might have been
@ -3508,9 +3472,9 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
uint8_t b = *src++;
#endif
// Convert to non-premultiplied color
*dst++ = sUnpremultiplyTable[a][r];
*dst++ = sUnpremultiplyTable[a][g];
*dst++ = sUnpremultiplyTable[a][b];
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + r];
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + g];
*dst++ = gfxUtils::sUnpremultiplyTable[a * 256 + b];
*dst++ = a;
}
src += srcStride - (dstWriteRect.width * 4);
@ -3521,25 +3485,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
return NS_OK;
}
void
CanvasRenderingContext2D::EnsurePremultiplyTable() {
if (sPremultiplyTable)
return;
// Infallably alloc the premultiply table.
sPremultiplyTable = new uint8_t[256][256];
// Like the unpremultiply table, it's important that we index the premultiply
// table with the alpha value as the first index to ensure good cache
// performance.
for (int a = 0; a <= 255; a++) {
for (int c = 0; c <= 255; c++) {
sPremultiplyTable[a][c] = (a * c + 254) / 255;
}
}
}
void
CanvasRenderingContext2D::EnsureErrorTarget()
{
@ -3662,9 +3607,6 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
return NS_ERROR_FAILURE;
}
// ensure premultiply table has been created
EnsurePremultiplyTable();
uint8_t *src = aData;
uint8_t *dst = imgsurf->Data();
@ -3677,15 +3619,15 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
// Convert to premultiplied color (losslessly if the input came from getImageData)
#ifdef IS_LITTLE_ENDIAN
*dst++ = sPremultiplyTable[a][b];
*dst++ = sPremultiplyTable[a][g];
*dst++ = sPremultiplyTable[a][r];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + b];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + g];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + r];
*dst++ = a;
#else
*dst++ = a;
*dst++ = sPremultiplyTable[a][r];
*dst++ = sPremultiplyTable[a][g];
*dst++ = sPremultiplyTable[a][b];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + r];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + g];
*dst++ = gfxUtils::sPremultiplyTable[a * 256 + b];
#endif
}
}

View File

@ -242,7 +242,7 @@ public:
void Stroke();
void Clip();
bool IsPointInPath(double x, double y);
bool MozIsPointInStroke(double x, double y);
bool IsPointInStroke(double x, double y);
void FillText(const nsAString& text, double x, double y,
const mozilla::dom::Optional<double>& maxWidth,
mozilla::ErrorResult& error);

View File

@ -896,12 +896,12 @@ WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializ
dom::WebGLContextAttributes& result = retval.SetValue();
gl::ContextFormat cf = gl->ActualFormat();
result.alpha = cf.alpha > 0;
result.depth = cf.depth > 0;
result.stencil = cf.stencil > 0;
result.antialias = cf.samples > 1;
result.premultipliedAlpha = mOptions.premultipliedAlpha;
result.preserveDrawingBuffer = mOptions.preserveDrawingBuffer;
result.mAlpha = cf.alpha > 0;
result.mDepth = cf.depth > 0;
result.mStencil = cf.stencil > 0;
result.mAntialias = cf.samples > 1;
result.mPremultipliedAlpha = mOptions.premultipliedAlpha;
result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
}
bool

View File

@ -978,7 +978,6 @@ protected:
nsLayoutUtils::SurfaceFromElementResult SurfaceFromElement(ElementType* aElement) {
MOZ_ASSERT(aElement);
uint32_t flags =
nsLayoutUtils::SFE_WANT_NEW_SURFACE |
nsLayoutUtils::SFE_WANT_IMAGE_SURFACE;
if (mPixelStoreColorspaceConversion == LOCAL_GL_NONE)

View File

@ -13,6 +13,7 @@ DIRS += webgl crossorigin chrome
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \
test_canvas.html \
test_isPointInStroke.html \
image_transparent50.png \
image_redtransparent.png \
image_yellow.png \
@ -98,7 +99,6 @@ MOCHITEST_FILES = \
test_toDataURL_lowercase_ascii.html \
test_toDataURL_parameters.html \
test_mozGetAsFile.html \
test_mozIsPointInStroke.html \
test_canvas_strokeStyle_getter.html \
test_bug613794.html \
test_bug753758.html \

View File

@ -1,188 +1,188 @@
# WebGL Reftests!
# If you add new tests, don't forget to add sanity (&nogl) tests! (if needed)
# Check that disabling works:
== webgl-disable-test.html?nogl wrapper.html?green.png
pref(webgl.disabled,true) == webgl-disable-test.html wrapper.html?green.png
# Basic WebGL tests:
# Do we get pixels to the screen at all?
# Try to just hit the different rendering paths here.
# Test: {aa, alpha, preserve, readback} = 16
== webgl-clear-test.html?nogl wrapper.html?green.png
== webgl-clear-test.html?__&_____&________ wrapper.html?green.png
== webgl-clear-test.html?aa&_____&________ wrapper.html?green.png
== webgl-clear-test.html?__&alpha&________ wrapper.html?green.png
== webgl-clear-test.html?aa&alpha&________ wrapper.html?green.png
== webgl-clear-test.html?__&_____&preserve wrapper.html?green.png
== webgl-clear-test.html?aa&_____&preserve wrapper.html?green.png
== webgl-clear-test.html?__&alpha&preserve wrapper.html?green.png
== webgl-clear-test.html?aa&alpha&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&__&_____&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&aa&_____&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&alpha&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&alpha&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&__&_____&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&aa&_____&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&alpha&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&alpha&preserve wrapper.html?green.png
# Check orientation:
== webgl-orientation-test.html?nogl wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&_____&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&_____&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&alpha&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&alpha&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&_____&preserve wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&_____&preserve wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&alpha&preserve wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&alpha&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&__&_____&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&aa&_____&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&alpha&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&alpha&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&__&_____&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&aa&_____&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&alpha&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&alpha&preserve wrapper.html?white-top-left.png
# Does we draw the correct color in the correct places with all context creation options?
# (Note that our context creation option matrix is 2^6 = 64)
== webgl-color-test.html?nogl wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
# Check a smaller selection for readback:
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&__&_____&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&aa&_____&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&alpha&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&alpha&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&__&_____&preserve wrapper.html?colors.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&aa&_____&preserve wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&alpha&preserve wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&alpha&preserve wrapper.html?colors.png
# Check alpha behavior:
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0&nogl wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0 wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0&nogl wrapper.html?black.png
== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0 wrapper.html?black.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&nogl wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0 wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha&nogl wrapper.html?white.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha wrapper.html?white.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0&nogl wrapper.html?half-colors.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0 wrapper.html?half-colors.png
# Test premult:
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&nogl wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&nogl wrapper.html?half-colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) fails-if(cocoaWidget||Android) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha wrapper.html?half-colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
# Test over-bright premult:
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
# Check for hanging framebuffer bindings:
== webgl-hanging-fb-test.html?nogl wrapper.html?green.png
== webgl-hanging-fb-test.html wrapper.html?green.png
== webgl-hanging-fb-test.html?aa wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-fb-test.html?readback wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-fb-test.html?readback&aa wrapper.html?green.png
== webgl-hanging-scissor-test.html wrapper.html?green.png
== webgl-hanging-scissor-test.html?aa wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-scissor-test.html?readback wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-scissor-test.html?readback&aa wrapper.html?green.png
# Check that our experimental prefs still work:
# 16bpp:
pref(webgl.prefer-16bpp,true) == webgl-color-test.html?16bpp wrapper.html?colors.png
pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?16bpp&readback wrapper.html?colors.png
# Force native GL (Windows):
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-clear-test.html?native-gl wrapper.html?green.png
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-orientation-test.html?native-gl wrapper.html?white-top-left.png
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-color-test.html?native-gl wrapper.html?colors.png
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,true) == webgl-color-test.html?native-gl&16bpp wrapper.html?colors.png
# WebGL Reftests!
# If you add new tests, don't forget to add sanity (&nogl) tests! (if needed)
# Check that disabling works:
== webgl-disable-test.html?nogl wrapper.html?green.png
pref(webgl.disabled,true) == webgl-disable-test.html wrapper.html?green.png
# Basic WebGL tests:
# Do we get pixels to the screen at all?
# Try to just hit the different rendering paths here.
# Test: {aa, alpha, preserve, readback} = 16
== webgl-clear-test.html?nogl wrapper.html?green.png
== webgl-clear-test.html?__&_____&________ wrapper.html?green.png
== webgl-clear-test.html?aa&_____&________ wrapper.html?green.png
== webgl-clear-test.html?__&alpha&________ wrapper.html?green.png
== webgl-clear-test.html?aa&alpha&________ wrapper.html?green.png
== webgl-clear-test.html?__&_____&preserve wrapper.html?green.png
== webgl-clear-test.html?aa&_____&preserve wrapper.html?green.png
== webgl-clear-test.html?__&alpha&preserve wrapper.html?green.png
== webgl-clear-test.html?aa&alpha&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&__&_____&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&aa&_____&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&alpha&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&alpha&________ wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&__&_____&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-clear-test.html?readback&aa&_____&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&__&alpha&preserve wrapper.html?green.png
pref(webgl.force-layers-readback,true) == webgl-clear-test.html?readback&aa&alpha&preserve wrapper.html?green.png
# Check orientation:
== webgl-orientation-test.html?nogl wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&_____&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&_____&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&alpha&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&alpha&________ wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&_____&preserve wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&_____&preserve wrapper.html?white-top-left.png
== webgl-orientation-test.html?__&alpha&preserve wrapper.html?white-top-left.png
== webgl-orientation-test.html?aa&alpha&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&__&_____&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&aa&_____&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&alpha&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&alpha&________ wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&__&_____&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-orientation-test.html?readback&aa&_____&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&__&alpha&preserve wrapper.html?white-top-left.png
pref(webgl.force-layers-readback,true) == webgl-orientation-test.html?readback&aa&alpha&preserve wrapper.html?white-top-left.png
# Does we draw the correct color in the correct places with all context creation options?
# (Note that our context creation option matrix is 2^6 = 64)
== webgl-color-test.html?nogl wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&________&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&preserve&_______ wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&________&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&_______&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&_____&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&_____&depth&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&_____&depth&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?__&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
== webgl-color-test.html?aa&alpha&depth&premult&preserve&stencil wrapper.html?colors.png
# Check a smaller selection for readback:
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&__&_____&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&aa&_____&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&alpha&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&alpha&________ wrapper.html?colors.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&__&_____&preserve wrapper.html?colors.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?readback&aa&_____&preserve wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&__&alpha&preserve wrapper.html?colors.png
pref(webgl.force-layers-readback,true) == webgl-color-test.html?readback&aa&alpha&preserve wrapper.html?colors.png
# Check alpha behavior:
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0&nogl wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=1.0 wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0&nogl wrapper.html?black.png
== webgl-color-alpha-test.html?colorVal=0.0&alphaVal=1.0 wrapper.html?black.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&nogl wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0 wrapper.html?colors.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha&nogl wrapper.html?white.png
== webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.0&alpha wrapper.html?white.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0&nogl wrapper.html?half-colors.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=1.0 wrapper.html?half-colors.png
# Test premult:
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&nogl wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&nogl wrapper.html?half-colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) fails-if(cocoaWidget||Android) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha wrapper.html?half-colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=0.5&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
# Test over-bright premult:
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult&nogl wrapper.html?colors-half-alpha.png
fuzzy(1,65536) fuzzy-if(Android,9,65536) == webgl-color-alpha-test.html?colorVal=1.0&alphaVal=0.5&alpha&premult wrapper.html?colors-half-alpha.png
# Check for hanging framebuffer bindings:
== webgl-hanging-fb-test.html?nogl wrapper.html?green.png
== webgl-hanging-fb-test.html wrapper.html?green.png
== webgl-hanging-fb-test.html?aa wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-fb-test.html?readback wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-fb-test.html?readback&aa wrapper.html?green.png
== webgl-hanging-scissor-test.html wrapper.html?green.png
== webgl-hanging-scissor-test.html?aa wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-scissor-test.html?readback wrapper.html?green.png
pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-hanging-scissor-test.html?readback&aa wrapper.html?green.png
# Check that our experimental prefs still work:
# 16bpp:
pref(webgl.prefer-16bpp,true) == webgl-color-test.html?16bpp wrapper.html?colors.png
pref(webgl.prefer-16bpp,true) pref(webgl.force-layers-readback,true) fails-if(nativeFennec) == webgl-color-test.html?16bpp&readback wrapper.html?colors.png
# Force native GL (Windows):
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-clear-test.html?native-gl wrapper.html?green.png
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-orientation-test.html?native-gl wrapper.html?white-top-left.png
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) == webgl-color-test.html?native-gl wrapper.html?colors.png
skip-if(!winWidget) pref(webgl.prefer-native-gl,true) pref(webgl.prefer-16bpp,true) == webgl-color-test.html?native-gl&16bpp wrapper.html?colors.png

View File

@ -0,0 +1,244 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Canvas test: isPointInStroke</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<script type="application/javascript">
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.lineWidth = 5;
ok(ctx.isPointInStroke(50, 25) === false, 'ctx.isPointInStroke(50, 25) === false');
ctx.beginPath();
ctx.rect(0, 0, 20, 20);
ok(ctx.isPointInStroke(-4, -4) === false, 'ctx.isPointInStroke(-4, -4) === false');
ok(ctx.isPointInStroke(4, 4) === false, 'ctx.isPointInStroke(4, 4) === false');
ok(ctx.isPointInStroke(16, 16) === false, 'ctx.isPointInStroke(16, 16) === false');
ok(ctx.isPointInStroke(24, 24) === false, 'ctx.isPointInStroke(24, 24) === false');
ok(ctx.isPointInStroke(-2, -2) === true, 'ctx.isPointInStroke(-2, -2) === true');
ok(ctx.isPointInStroke(2, 2) === true, 'ctx.isPointInStroke(2, 2) === true');
ok(ctx.isPointInStroke(18, 18) === true, 'ctx.isPointInStroke(18, 18) === true');
ok(ctx.isPointInStroke(22, 22) === true, 'ctx.isPointInStroke(22, 22) === true');
ctx.beginPath();
ctx.rect(25, 25, 20, 20);
ok(ctx.isPointInStroke(21, 21) === false, 'ctx.isPointInStroke(21, 21) === false');
ok(ctx.isPointInStroke(29, 29) === false, 'ctx.isPointInStroke(29, 29) === false');
ok(ctx.isPointInStroke(42, 42) === false, 'ctx.isPointInStroke(42, 42) === false');
ok(ctx.isPointInStroke(50, 50) === false, 'ctx.isPointInStroke(50, 50) === false');
ok(ctx.isPointInStroke(23, 23) === true, 'ctx.isPointInStroke(23, 23) === true');
ok(ctx.isPointInStroke(27, 27) === true, 'ctx.isPointInStroke(27, 27) === true');
ok(ctx.isPointInStroke(43, 43) === true, 'ctx.isPointInStroke(43, 43) === true');
ok(ctx.isPointInStroke(47, 47) === true, 'ctx.isPointInStroke(47, 47) === true');
ctx.beginPath();
ctx.moveTo(25, 25);
ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
ok(ctx.isPointInStroke(23, 26) === false, 'ctx.isPointInStroke(23, 26) === false');
ok(ctx.isPointInStroke(75, 23) === false, 'ctx.isPointInStroke(75, 23) === false');
ok(ctx.isPointInStroke(37, 8) === false, 'ctx.isPointInStroke(37, 8) === false');
ok(ctx.isPointInStroke(61, 42) === false, 'ctx.isPointInStroke(61, 42) === false');
ok(ctx.isPointInStroke(24, 24) === true, 'ctx.isPointInStroke(24, 24) === true');
ok(ctx.isPointInStroke(74, 25) === true, 'ctx.isPointInStroke(74, 25) === true');
ok(ctx.isPointInStroke(37, 2) === true, 'ctx.isPointInStroke(37, 2) === true');
ok(ctx.isPointInStroke(61, 47) === true, 'ctx.isPointInStroke(61, 47) === true');
ctx.beginPath();
ctx.arc(50, 25, 10, 0, Math.PI, false);
ok(ctx.isPointInStroke(39, 23) === false, 'ctx.isPointInStroke(39, 23) === false');
ok(ctx.isPointInStroke(50, 15) === false, 'ctx.isPointInStroke(50, 15) === false');
ok(ctx.isPointInStroke(60, 23) === false, 'ctx.isPointInStroke(60, 23) === false');
ok(ctx.isPointInStroke(50, 25) === false, 'ctx.isPointInStroke(50, 25) === false');
ok(ctx.isPointInStroke(39, 26) === true, 'ctx.isPointInStroke(39, 26) === true');
ok(ctx.isPointInStroke(45, 33) === true, 'ctx.isPointInStroke(45, 33) === true');
ok(ctx.isPointInStroke(53, 33) === true, 'ctx.isPointInStroke(53, 33) === true');
ok(ctx.isPointInStroke(59, 26) === true, 'ctx.isPointInStroke(59, 26) === true');
ctx.beginPath();
ctx.arc(50, 25, 10, 0, 2 * Math.PI, false);
ok(ctx.isPointInStroke(34, 25) === false, 'ctx.isPointInStroke(34, 25) === false');
ok(ctx.isPointInStroke(44, 25) === false, 'ctx.isPointInStroke(44, 25) === false');
ok(ctx.isPointInStroke(49, 30) === false, 'ctx.isPointInStroke(49, 30) === false');
ok(ctx.isPointInStroke(49, 40) === false, 'ctx.isPointInStroke(49, 40) === false');
ok(ctx.isPointInStroke(39, 23) === true, 'ctx.isPointInStroke(39, 23) === true');
ok(ctx.isPointInStroke(50, 15) === true, 'ctx.isPointInStroke(50, 15) === true');
ok(ctx.isPointInStroke(60, 23) === true, 'ctx.isPointInStroke(60, 23) === true');
ok(ctx.isPointInStroke(49, 34) === true, 'ctx.isPointInStroke(49, 34) === true');
ctx.beginPath();
ctx.save();
ctx.translate(20, 20);
ctx.rect(0, 0, 20, 20);
ok(ctx.isPointInStroke(16, 16) === false, 'ctx.isPointInStroke(16, 16) === false');
ok(ctx.isPointInStroke(24, 24) === false, 'ctx.isPointInStroke(24, 24) === false');
ok(ctx.isPointInStroke(36, 36) === false, 'ctx.isPointInStroke(36, 36) === false');
ok(ctx.isPointInStroke(44, 44) === false, 'ctx.isPointInStroke(44, 44) === false');
ok(ctx.isPointInStroke(18, 18) === true, 'ctx.isPointInStroke(18, 18) === true');
ok(ctx.isPointInStroke(22, 22) === true, 'ctx.isPointInStroke(22, 22) === true');
ok(ctx.isPointInStroke(38, 38) === true, 'ctx.isPointInStroke(38, 38) === true');
ok(ctx.isPointInStroke(42, 42) === true, 'ctx.isPointInStroke(42, 42) === true');
ctx.restore();
ctx.beginPath();
ctx.save();
ctx.scale(-1, 1);
ctx.rect(-30, 20, 20, 20);
ok(ctx.isPointInStroke(16, 16) === false, 'ctx.isPointInStroke(16, 16) === false');
ok(ctx.isPointInStroke(14, 24) === false, 'ctx.isPointInStroke(14, 24) === false');
ok(ctx.isPointInStroke(26, 36) === false, 'ctx.isPointInStroke(26, 36) === false');
ok(ctx.isPointInStroke(34, 44) === false, 'ctx.isPointInStroke(34, 44) === false');
ok(ctx.isPointInStroke(8, 18) === true, 'ctx.isPointInStroke(8, 18) === true');
ok(ctx.isPointInStroke(12, 22) === true, 'ctx.isPointInStroke(12, 22) === true');
ok(ctx.isPointInStroke(28, 38) === true, 'ctx.isPointInStroke(28, 38) === true');
ok(ctx.isPointInStroke(32, 42) === true, 'ctx.isPointInStroke(32, 42) === true');
ctx.restore();
ctx.beginPath();
ctx.save();
ctx.lineWidth = 2;
ctx.translate(50, 25);
ctx.rotate(180 * Math.PI / 180);
ctx.scale(5, 5);
ctx.arc(0, 0, 2, 0, Math.PI, false);
ok(ctx.isPointInStroke(39, 26) === false, 'ctx.isPointInStroke(39, 26) === false');
ok(ctx.isPointInStroke(45, 33) === false, 'ctx.isPointInStroke(45, 33) === false');
ok(ctx.isPointInStroke(53, 33) === false, 'ctx.isPointInStroke(53, 33) === false');
ok(ctx.isPointInStroke(59, 26) === false, 'ctx.isPointInStroke(59, 26) === false');
ok(ctx.isPointInStroke(39, 23) === true, 'ctx.isPointInStroke(39, 23) === true');
ok(ctx.isPointInStroke(45, 15) === true, 'ctx.isPointInStroke(50, 15) === true');
ok(ctx.isPointInStroke(55, 15) === true, 'ctx.isPointInStroke(50, 25) === true');
ok(ctx.isPointInStroke(60, 23) === true, 'ctx.isPointInStroke(60, 23) === true');
ctx.restore();
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(30, 10);
ctx.save();
ctx.lineWidth = 2;
ctx.scale(5, 5);
ctx.lineTo(6, 6);
ctx.lineTo(2, 6);
ctx.restore();
ctx.closePath();
ok(ctx.isPointInStroke(6, 6) === false, 'ctx.isPointInStroke(6, 6) === false');
ok(ctx.isPointInStroke(14, 14) === false, 'ctx.isPointInStroke(14, 14) === false');
ok(ctx.isPointInStroke(26, 26) === false, 'ctx.isPointInStroke(26, 26) === false');
ok(ctx.isPointInStroke(34, 34) === false, 'ctx.isPointInStroke(34, 34) === false');
ok(ctx.isPointInStroke(8, 8) === true, 'ctx.isPointInStroke(8, 8) === true');
ok(ctx.isPointInStroke(12, 12) === true, 'ctx.isPointInStroke(12, 12) === true');
ok(ctx.isPointInStroke(28, 28) === true, 'ctx.isPointInStroke(28, 28) === true');
ok(ctx.isPointInStroke(32, 32) === true, 'ctx.isPointInStroke(32, 32) === true');
ctx.beginPath();
ctx.rect(-30, -30, 20, 20);
ok(ctx.isPointInStroke(-34, -34) === false, 'ctx.isPointInStroke(-34, -34) === false');
ok(ctx.isPointInStroke(-26, -26) === false, 'ctx.isPointInStroke(-26, -26) === false');
ok(ctx.isPointInStroke(-14, -14) === false, 'ctx.isPointInStroke(-14, -14) === false');
ok(ctx.isPointInStroke(-6, -6) === false, 'ctx.isPointInStroke(-6, -6) === false');
ok(ctx.isPointInStroke(-32, -32) === true, 'ctx.isPointInStroke(-32, -32) === true');
ok(ctx.isPointInStroke(-28, -28) === true, 'ctx.isPointInStroke(-28, -28) === true');
ok(ctx.isPointInStroke(-12, -12) === true, 'ctx.isPointInStroke(-12, -12) === true');
ok(ctx.isPointInStroke(-8, -8) === true, 'ctx.isPointInStroke(-8, -8) === true');
ctx.beginPath();
ctx.moveTo(20, 25);
ctx.lineTo(80, 25);
ok(ctx.isPointInStroke(19, 25) === false, 'ctx.isPointInStroke(19, 25) === false');
ok(ctx.isPointInStroke(50, 21) === false, 'ctx.isPointInStroke(50, 21) === false');
ok(ctx.isPointInStroke(81, 25) === false, 'ctx.isPointInStroke(81, 25) === false');
ok(ctx.isPointInStroke(50, 29) === false, 'ctx.isPointInStroke(50, 29) === false');
ok(ctx.isPointInStroke(21, 25) === true, 'ctx.isPointInStroke(21, 25) === true');
ok(ctx.isPointInStroke(50, 23) === true, 'ctx.isPointInStroke(50, 23) === true');
ok(ctx.isPointInStroke(79, 25) === true, 'ctx.isPointInStroke(79, 25) === true');
ok(ctx.isPointInStroke(50, 27) === true, 'ctx.isPointInStroke(50, 27) === true');
ctx.lineWidth = 15;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(20, 25);
ctx.lineTo(80, 25);
ok(ctx.isPointInStroke(13, 18) === false, 'ctx.isPointInStroke(13, 18) === false');
ok(ctx.isPointInStroke(13, 31) === false, 'ctx.isPointInStroke(13, 31) === false');
ok(ctx.isPointInStroke(86, 18) === false, 'ctx.isPointInStroke(86, 18) === false');
ok(ctx.isPointInStroke(86, 31) === false, 'ctx.isPointInStroke(86, 31) === false');
ok(ctx.isPointInStroke(13, 25) === true, 'ctx.isPointInStroke(13, 25) === true');
ok(ctx.isPointInStroke(50, 18) === true, 'ctx.isPointInStroke(50, 18) === true');
ok(ctx.isPointInStroke(86, 25) === true, 'ctx.isPointInStroke(86, 25) === true');
ok(ctx.isPointInStroke(50, 31) === true, 'ctx.isPointInStroke(50, 31) === true');
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(20, 15);
ctx.lineTo(80, 15);
ctx.lineTo(80, 35);
ok(ctx.isPointInStroke(86, 8) === false, 'ctx.isPointInStroke(86, 8) === false');
ok(ctx.isPointInStroke(70, 24) === false, 'ctx.isPointInStroke(70, 24) === false');
ok(ctx.isPointInStroke(73, 41) === false, 'ctx.isPointInStroke(73, 41) === false');
ok(ctx.isPointInStroke(86, 41) === false, 'ctx.isPointInStroke(86, 41) === false');
ok(ctx.isPointInStroke(14, 15) === true, 'ctx.isPointInStroke(14, 15) === true');
ok(ctx.isPointInStroke(81, 15) === true, 'ctx.isPointInStroke(81, 15) === true');
ok(ctx.isPointInStroke(79, 41) === true, 'ctx.isPointInStroke(79, 41) === true');
ok(ctx.isPointInStroke(73, 21) === true, 'ctx.isPointInStroke(73, 21) === true');
</script>
</pre>
</body>
</html>

View File

@ -1,244 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Canvas test: mozIsPointInStroke</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<canvas id="c" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
<script type="application/javascript">
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.lineWidth = 5;
ok(ctx.mozIsPointInStroke(50, 25) === false, 'ctx.mozIsPointInStroke(50, 25) === false');
ctx.beginPath();
ctx.rect(0, 0, 20, 20);
ok(ctx.mozIsPointInStroke(-4, -4) === false, 'ctx.mozIsPointInStroke(-4, -4) === false');
ok(ctx.mozIsPointInStroke(4, 4) === false, 'ctx.mozIsPointInStroke(4, 4) === false');
ok(ctx.mozIsPointInStroke(16, 16) === false, 'ctx.mozIsPointInStroke(16, 16) === false');
ok(ctx.mozIsPointInStroke(24, 24) === false, 'ctx.mozIsPointInStroke(24, 24) === false');
ok(ctx.mozIsPointInStroke(-2, -2) === true, 'ctx.mozIsPointInStroke(-2, -2) === true');
ok(ctx.mozIsPointInStroke(2, 2) === true, 'ctx.mozIsPointInStroke(2, 2) === true');
ok(ctx.mozIsPointInStroke(18, 18) === true, 'ctx.mozIsPointInStroke(18, 18) === true');
ok(ctx.mozIsPointInStroke(22, 22) === true, 'ctx.mozIsPointInStroke(22, 22) === true');
ctx.beginPath();
ctx.rect(25, 25, 20, 20);
ok(ctx.mozIsPointInStroke(21, 21) === false, 'ctx.mozIsPointInStroke(21, 21) === false');
ok(ctx.mozIsPointInStroke(29, 29) === false, 'ctx.mozIsPointInStroke(29, 29) === false');
ok(ctx.mozIsPointInStroke(42, 42) === false, 'ctx.mozIsPointInStroke(42, 42) === false');
ok(ctx.mozIsPointInStroke(50, 50) === false, 'ctx.mozIsPointInStroke(50, 50) === false');
ok(ctx.mozIsPointInStroke(23, 23) === true, 'ctx.mozIsPointInStroke(23, 23) === true');
ok(ctx.mozIsPointInStroke(27, 27) === true, 'ctx.mozIsPointInStroke(27, 27) === true');
ok(ctx.mozIsPointInStroke(43, 43) === true, 'ctx.mozIsPointInStroke(43, 43) === true');
ok(ctx.mozIsPointInStroke(47, 47) === true, 'ctx.mozIsPointInStroke(47, 47) === true');
ctx.beginPath();
ctx.moveTo(25, 25);
ctx.bezierCurveTo(50, -50, 50, 100, 75, 25);
ok(ctx.mozIsPointInStroke(23, 26) === false, 'ctx.mozIsPointInStroke(23, 26) === false');
ok(ctx.mozIsPointInStroke(75, 23) === false, 'ctx.mozIsPointInStroke(75, 23) === false');
ok(ctx.mozIsPointInStroke(37, 8) === false, 'ctx.mozIsPointInStroke(37, 8) === false');
ok(ctx.mozIsPointInStroke(61, 42) === false, 'ctx.mozIsPointInStroke(61, 42) === false');
ok(ctx.mozIsPointInStroke(24, 24) === true, 'ctx.mozIsPointInStroke(24, 24) === true');
ok(ctx.mozIsPointInStroke(74, 25) === true, 'ctx.mozIsPointInStroke(74, 25) === true');
ok(ctx.mozIsPointInStroke(37, 2) === true, 'ctx.mozIsPointInStroke(37, 2) === true');
ok(ctx.mozIsPointInStroke(61, 47) === true, 'ctx.mozIsPointInStroke(61, 47) === true');
ctx.beginPath();
ctx.arc(50, 25, 10, 0, Math.PI, false);
ok(ctx.mozIsPointInStroke(39, 23) === false, 'ctx.mozIsPointInStroke(39, 23) === false');
ok(ctx.mozIsPointInStroke(50, 15) === false, 'ctx.mozIsPointInStroke(50, 15) === false');
ok(ctx.mozIsPointInStroke(60, 23) === false, 'ctx.mozIsPointInStroke(60, 23) === false');
ok(ctx.mozIsPointInStroke(50, 25) === false, 'ctx.mozIsPointInStroke(50, 25) === false');
ok(ctx.mozIsPointInStroke(39, 26) === true, 'ctx.mozIsPointInStroke(39, 26) === true');
ok(ctx.mozIsPointInStroke(45, 33) === true, 'ctx.mozIsPointInStroke(45, 33) === true');
ok(ctx.mozIsPointInStroke(53, 33) === true, 'ctx.mozIsPointInStroke(53, 33) === true');
ok(ctx.mozIsPointInStroke(59, 26) === true, 'ctx.mozIsPointInStroke(59, 26) === true');
ctx.beginPath();
ctx.arc(50, 25, 10, 0, 2 * Math.PI, false);
ok(ctx.mozIsPointInStroke(34, 25) === false, 'ctx.mozIsPointInStroke(34, 25) === false');
ok(ctx.mozIsPointInStroke(44, 25) === false, 'ctx.mozIsPointInStroke(44, 25) === false');
ok(ctx.mozIsPointInStroke(49, 30) === false, 'ctx.mozIsPointInStroke(49, 30) === false');
ok(ctx.mozIsPointInStroke(49, 40) === false, 'ctx.mozIsPointInStroke(49, 40) === false');
ok(ctx.mozIsPointInStroke(39, 23) === true, 'ctx.mozIsPointInStroke(39, 23) === true');
ok(ctx.mozIsPointInStroke(50, 15) === true, 'ctx.mozIsPointInStroke(50, 15) === true');
ok(ctx.mozIsPointInStroke(60, 23) === true, 'ctx.mozIsPointInStroke(60, 23) === true');
ok(ctx.mozIsPointInStroke(49, 34) === true, 'ctx.mozIsPointInStroke(49, 34) === true');
ctx.beginPath();
ctx.save();
ctx.translate(20, 20);
ctx.rect(0, 0, 20, 20);
ok(ctx.mozIsPointInStroke(16, 16) === false, 'ctx.mozIsPointInStroke(16, 16) === false');
ok(ctx.mozIsPointInStroke(24, 24) === false, 'ctx.mozIsPointInStroke(24, 24) === false');
ok(ctx.mozIsPointInStroke(36, 36) === false, 'ctx.mozIsPointInStroke(36, 36) === false');
ok(ctx.mozIsPointInStroke(44, 44) === false, 'ctx.mozIsPointInStroke(44, 44) === false');
ok(ctx.mozIsPointInStroke(18, 18) === true, 'ctx.mozIsPointInStroke(18, 18) === true');
ok(ctx.mozIsPointInStroke(22, 22) === true, 'ctx.mozIsPointInStroke(22, 22) === true');
ok(ctx.mozIsPointInStroke(38, 38) === true, 'ctx.mozIsPointInStroke(38, 38) === true');
ok(ctx.mozIsPointInStroke(42, 42) === true, 'ctx.mozIsPointInStroke(42, 42) === true');
ctx.restore();
ctx.beginPath();
ctx.save();
ctx.scale(-1, 1);
ctx.rect(-30, 20, 20, 20);
ok(ctx.mozIsPointInStroke(16, 16) === false, 'ctx.mozIsPointInStroke(16, 16) === false');
ok(ctx.mozIsPointInStroke(14, 24) === false, 'ctx.mozIsPointInStroke(14, 24) === false');
ok(ctx.mozIsPointInStroke(26, 36) === false, 'ctx.mozIsPointInStroke(26, 36) === false');
ok(ctx.mozIsPointInStroke(34, 44) === false, 'ctx.mozIsPointInStroke(34, 44) === false');
ok(ctx.mozIsPointInStroke(8, 18) === true, 'ctx.mozIsPointInStroke(8, 18) === true');
ok(ctx.mozIsPointInStroke(12, 22) === true, 'ctx.mozIsPointInStroke(12, 22) === true');
ok(ctx.mozIsPointInStroke(28, 38) === true, 'ctx.mozIsPointInStroke(28, 38) === true');
ok(ctx.mozIsPointInStroke(32, 42) === true, 'ctx.mozIsPointInStroke(32, 42) === true');
ctx.restore();
ctx.beginPath();
ctx.save();
ctx.lineWidth = 2;
ctx.translate(50, 25);
ctx.rotate(180 * Math.PI / 180);
ctx.scale(5, 5);
ctx.arc(0, 0, 2, 0, Math.PI, false);
ok(ctx.mozIsPointInStroke(39, 26) === false, 'ctx.mozIsPointInStroke(39, 26) === false');
ok(ctx.mozIsPointInStroke(45, 33) === false, 'ctx.mozIsPointInStroke(45, 33) === false');
ok(ctx.mozIsPointInStroke(53, 33) === false, 'ctx.mozIsPointInStroke(53, 33) === false');
ok(ctx.mozIsPointInStroke(59, 26) === false, 'ctx.mozIsPointInStroke(59, 26) === false');
ok(ctx.mozIsPointInStroke(39, 23) === true, 'ctx.mozIsPointInStroke(39, 23) === true');
ok(ctx.mozIsPointInStroke(45, 15) === true, 'ctx.mozIsPointInStroke(50, 15) === true');
ok(ctx.mozIsPointInStroke(55, 15) === true, 'ctx.mozIsPointInStroke(50, 25) === true');
ok(ctx.mozIsPointInStroke(60, 23) === true, 'ctx.mozIsPointInStroke(60, 23) === true');
ctx.restore();
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(30, 10);
ctx.save();
ctx.lineWidth = 2;
ctx.scale(5, 5);
ctx.lineTo(6, 6);
ctx.lineTo(2, 6);
ctx.restore();
ctx.closePath();
ok(ctx.mozIsPointInStroke(6, 6) === false, 'ctx.mozIsPointInStroke(6, 6) === false');
ok(ctx.mozIsPointInStroke(14, 14) === false, 'ctx.mozIsPointInStroke(14, 14) === false');
ok(ctx.mozIsPointInStroke(26, 26) === false, 'ctx.mozIsPointInStroke(26, 26) === false');
ok(ctx.mozIsPointInStroke(34, 34) === false, 'ctx.mozIsPointInStroke(34, 34) === false');
ok(ctx.mozIsPointInStroke(8, 8) === true, 'ctx.mozIsPointInStroke(8, 8) === true');
ok(ctx.mozIsPointInStroke(12, 12) === true, 'ctx.mozIsPointInStroke(12, 12) === true');
ok(ctx.mozIsPointInStroke(28, 28) === true, 'ctx.mozIsPointInStroke(28, 28) === true');
ok(ctx.mozIsPointInStroke(32, 32) === true, 'ctx.mozIsPointInStroke(32, 32) === true');
ctx.beginPath();
ctx.rect(-30, -30, 20, 20);
ok(ctx.mozIsPointInStroke(-34, -34) === false, 'ctx.mozIsPointInStroke(-34, -34) === false');
ok(ctx.mozIsPointInStroke(-26, -26) === false, 'ctx.mozIsPointInStroke(-26, -26) === false');
ok(ctx.mozIsPointInStroke(-14, -14) === false, 'ctx.mozIsPointInStroke(-14, -14) === false');
ok(ctx.mozIsPointInStroke(-6, -6) === false, 'ctx.mozIsPointInStroke(-6, -6) === false');
ok(ctx.mozIsPointInStroke(-32, -32) === true, 'ctx.mozIsPointInStroke(-32, -32) === true');
ok(ctx.mozIsPointInStroke(-28, -28) === true, 'ctx.mozIsPointInStroke(-28, -28) === true');
ok(ctx.mozIsPointInStroke(-12, -12) === true, 'ctx.mozIsPointInStroke(-12, -12) === true');
ok(ctx.mozIsPointInStroke(-8, -8) === true, 'ctx.mozIsPointInStroke(-8, -8) === true');
ctx.beginPath();
ctx.moveTo(20, 25);
ctx.lineTo(80, 25);
ok(ctx.mozIsPointInStroke(19, 25) === false, 'ctx.mozIsPointInStroke(19, 25) === false');
ok(ctx.mozIsPointInStroke(50, 21) === false, 'ctx.mozIsPointInStroke(50, 21) === false');
ok(ctx.mozIsPointInStroke(81, 25) === false, 'ctx.mozIsPointInStroke(81, 25) === false');
ok(ctx.mozIsPointInStroke(50, 29) === false, 'ctx.mozIsPointInStroke(50, 29) === false');
ok(ctx.mozIsPointInStroke(21, 25) === true, 'ctx.mozIsPointInStroke(21, 25) === true');
ok(ctx.mozIsPointInStroke(50, 23) === true, 'ctx.mozIsPointInStroke(50, 23) === true');
ok(ctx.mozIsPointInStroke(79, 25) === true, 'ctx.mozIsPointInStroke(79, 25) === true');
ok(ctx.mozIsPointInStroke(50, 27) === true, 'ctx.mozIsPointInStroke(50, 27) === true');
ctx.lineWidth = 15;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(20, 25);
ctx.lineTo(80, 25);
ok(ctx.mozIsPointInStroke(13, 18) === false, 'ctx.mozIsPointInStroke(13, 18) === false');
ok(ctx.mozIsPointInStroke(13, 31) === false, 'ctx.mozIsPointInStroke(13, 31) === false');
ok(ctx.mozIsPointInStroke(86, 18) === false, 'ctx.mozIsPointInStroke(86, 18) === false');
ok(ctx.mozIsPointInStroke(86, 31) === false, 'ctx.mozIsPointInStroke(86, 31) === false');
ok(ctx.mozIsPointInStroke(13, 25) === true, 'ctx.mozIsPointInStroke(13, 25) === true');
ok(ctx.mozIsPointInStroke(50, 18) === true, 'ctx.mozIsPointInStroke(50, 18) === true');
ok(ctx.mozIsPointInStroke(86, 25) === true, 'ctx.mozIsPointInStroke(86, 25) === true');
ok(ctx.mozIsPointInStroke(50, 31) === true, 'ctx.mozIsPointInStroke(50, 31) === true');
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(20, 15);
ctx.lineTo(80, 15);
ctx.lineTo(80, 35);
ok(ctx.mozIsPointInStroke(86, 8) === false, 'ctx.mozIsPointInStroke(86, 8) === false');
ok(ctx.mozIsPointInStroke(70, 24) === false, 'ctx.mozIsPointInStroke(70, 24) === false');
ok(ctx.mozIsPointInStroke(73, 41) === false, 'ctx.mozIsPointInStroke(73, 41) === false');
ok(ctx.mozIsPointInStroke(86, 41) === false, 'ctx.mozIsPointInStroke(86, 41) === false');
ok(ctx.mozIsPointInStroke(14, 15) === true, 'ctx.mozIsPointInStroke(14, 15) === true');
ok(ctx.mozIsPointInStroke(81, 15) === true, 'ctx.mozIsPointInStroke(81, 15) === true');
ok(ctx.mozIsPointInStroke(79, 41) === true, 'ctx.mozIsPointInStroke(79, 41) === true');
ok(ctx.mozIsPointInStroke(73, 21) === true, 'ctx.mozIsPointInStroke(73, 21) === true');
</script>
</pre>
</body>
</html>

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