зеркало из https://github.com/mozilla/pjs.git
Merge m-c to s-c.
This commit is contained in:
Коммит
82c5d3b41b
|
@ -67,7 +67,7 @@
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsEventStates.h"
|
#include "nsEventStates.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
#include "nsIDOMCharacterData.h"
|
#include "nsIDOMCharacterData.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -799,38 +799,11 @@ Accessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||||
if (!accessible)
|
if (!accessible)
|
||||||
return fallbackAnswer;
|
return fallbackAnswer;
|
||||||
|
|
||||||
if (accessible == this) {
|
// Hurray! We have an accessible for the frame that layout gave us.
|
||||||
// Manually walk through accessible children and see if the are within this
|
|
||||||
// point. Skip offscreen or invisible accessibles. This takes care of cases
|
|
||||||
// where layout won't walk into things for us, such as image map areas and
|
|
||||||
// sub documents (XXX: subdocuments should be handled by methods of
|
|
||||||
// OuterDocAccessibles).
|
|
||||||
PRUint32 childCount = ChildCount();
|
|
||||||
for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
|
|
||||||
Accessible* child = GetChildAt(childIdx);
|
|
||||||
|
|
||||||
PRInt32 childX, childY, childWidth, childHeight;
|
|
||||||
child->GetBounds(&childX, &childY, &childWidth, &childHeight);
|
|
||||||
if (aX >= childX && aX < childX + childWidth &&
|
|
||||||
aY >= childY && aY < childY + childHeight &&
|
|
||||||
(child->State() & states::INVISIBLE) == 0) {
|
|
||||||
|
|
||||||
if (aWhichChild == eDeepestChild)
|
|
||||||
return child->ChildAtPoint(aX, aY, eDeepestChild);
|
|
||||||
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The point is in this accessible but not in a child. We are allowed to
|
|
||||||
// return |this| as the answer.
|
|
||||||
return accessible;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since DOM node of obtained accessible may be out of flow then we should
|
// Since DOM node of obtained accessible may be out of flow then we should
|
||||||
// ensure obtained accessible is a child of this accessible.
|
// ensure obtained accessible is a child of this accessible.
|
||||||
Accessible* child = accessible;
|
Accessible* child = accessible;
|
||||||
while (true) {
|
while (child != this) {
|
||||||
Accessible* parent = child->Parent();
|
Accessible* parent = child->Parent();
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
// Reached the top of the hierarchy. These bounds were inside an
|
// Reached the top of the hierarchy. These bounds were inside an
|
||||||
|
@ -838,13 +811,37 @@ Accessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||||
return fallbackAnswer;
|
return fallbackAnswer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent == this)
|
// If we landed on a legitimate child of |this|, and we want the direct
|
||||||
return aWhichChild == eDeepestChild ? accessible : child;
|
// child, return it here.
|
||||||
|
if (parent == this && aWhichChild == eDirectChild)
|
||||||
|
return child;
|
||||||
|
|
||||||
child = parent;
|
child = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nsnull;
|
// Manually walk through accessible children and see if the are within this
|
||||||
|
// point. Skip offscreen or invisible accessibles. This takes care of cases
|
||||||
|
// where layout won't walk into things for us, such as image map areas and
|
||||||
|
// sub documents (XXX: subdocuments should be handled by methods of
|
||||||
|
// OuterDocAccessibles).
|
||||||
|
PRUint32 childCount = accessible->ChildCount();
|
||||||
|
for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
|
||||||
|
Accessible* child = accessible->GetChildAt(childIdx);
|
||||||
|
|
||||||
|
PRInt32 childX, childY, childWidth, childHeight;
|
||||||
|
child->GetBounds(&childX, &childY, &childWidth, &childHeight);
|
||||||
|
if (aX >= childX && aX < childX + childWidth &&
|
||||||
|
aY >= childY && aY < childY + childHeight &&
|
||||||
|
(child->State() & states::INVISIBLE) == 0) {
|
||||||
|
|
||||||
|
if (aWhichChild == eDeepestChild)
|
||||||
|
return child->ChildAtPoint(aX, aY, eDeepestChild);
|
||||||
|
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessible;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIAccessible getChildAtPoint(in long x, in long y)
|
// nsIAccessible getChildAtPoint(in long x, in long y)
|
||||||
|
|
|
@ -232,8 +232,9 @@ var AccessFu = {
|
||||||
|
|
||||||
let presenterContext =
|
let presenterContext =
|
||||||
new PresenterContext(position, event.oldAccessible);
|
new PresenterContext(position, event.oldAccessible);
|
||||||
|
let reason = event.reason;
|
||||||
this.presenters.forEach(
|
this.presenters.forEach(
|
||||||
function(p) { p.pivotChanged(presenterContext); });
|
function(p) { p.pivotChanged(presenterContext, reason); });
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,10 @@ Presenter.prototype = {
|
||||||
* The virtual cursor's position changed.
|
* The virtual cursor's position changed.
|
||||||
* @param {PresenterContext} aContext the context object for the new pivot
|
* @param {PresenterContext} aContext the context object for the new pivot
|
||||||
* position.
|
* position.
|
||||||
|
* @param {int} aReason the reason for the pivot change.
|
||||||
|
* See nsIAccessiblePivot.
|
||||||
*/
|
*/
|
||||||
pivotChanged: function pivotChanged(aContext) {},
|
pivotChanged: function pivotChanged(aContext, aReason) {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An object's action has been invoked.
|
* An object's action has been invoked.
|
||||||
|
@ -140,7 +142,7 @@ VisualPresenter.prototype = {
|
||||||
this._highlight(this._currentObject);
|
this._highlight(this._currentObject);
|
||||||
},
|
},
|
||||||
|
|
||||||
pivotChanged: function VisualPresenter_pivotChanged(aContext) {
|
pivotChanged: function VisualPresenter_pivotChanged(aContext, aReason) {
|
||||||
this._currentObject = aContext.accessible;
|
this._currentObject = aContext.accessible;
|
||||||
|
|
||||||
if (!aContext.accessible) {
|
if (!aContext.accessible) {
|
||||||
|
@ -159,7 +161,7 @@ VisualPresenter.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
tabSelected: function VisualPresenter_tabSelected(aDocContext, aVCContext) {
|
tabSelected: function VisualPresenter_tabSelected(aDocContext, aVCContext) {
|
||||||
this.pivotChanged(aVCContext);
|
this.pivotChanged(aVCContext, Ci.nsIAccessiblePivot.REASON_NONE);
|
||||||
},
|
},
|
||||||
|
|
||||||
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
|
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
|
||||||
|
@ -229,17 +231,53 @@ AndroidPresenter.prototype = {
|
||||||
ANDROID_VIEW_FOCUSED: 0x08,
|
ANDROID_VIEW_FOCUSED: 0x08,
|
||||||
ANDROID_VIEW_TEXT_CHANGED: 0x10,
|
ANDROID_VIEW_TEXT_CHANGED: 0x10,
|
||||||
ANDROID_WINDOW_STATE_CHANGED: 0x20,
|
ANDROID_WINDOW_STATE_CHANGED: 0x20,
|
||||||
|
ANDROID_VIEW_HOVER_ENTER: 0x80,
|
||||||
|
ANDROID_VIEW_HOVER_EXIT: 0x100,
|
||||||
|
ANDROID_VIEW_SCROLLED: 0x1000,
|
||||||
|
|
||||||
pivotChanged: function AndroidPresenter_pivotChanged(aContext) {
|
attach: function AndroidPresenter_attach(aWindow) {
|
||||||
|
this.chromeWin = aWindow;
|
||||||
|
},
|
||||||
|
|
||||||
|
pivotChanged: function AndroidPresenter_pivotChanged(aContext, aReason) {
|
||||||
if (!aContext.accessible)
|
if (!aContext.accessible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
let isExploreByTouch = (aReason == Ci.nsIAccessiblePivot.REASON_POINT &&
|
||||||
|
Utils.AndroidSdkVersion >= 14);
|
||||||
|
|
||||||
|
if (isExploreByTouch) {
|
||||||
|
// This isn't really used by TalkBack so this is a half-hearted attempt
|
||||||
|
// for now.
|
||||||
|
this.sendMessageToJava({
|
||||||
|
gecko: {
|
||||||
|
type: 'Accessibility:Event',
|
||||||
|
eventType: this.ANDROID_VIEW_HOVER_EXIT,
|
||||||
|
text: []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let output = [];
|
let output = [];
|
||||||
aContext.newAncestry.forEach(
|
|
||||||
function(acc) {
|
if (isExploreByTouch) {
|
||||||
output.push.apply(output, UtteranceGenerator.genForObject(acc));
|
// Just provide the parent for some context, no need to utter the entire
|
||||||
|
// ancestry change since it doesn't make sense in spatial navigation.
|
||||||
|
for (var i = aContext.newAncestry.length - 1; i >= 0; i--) {
|
||||||
|
let utter = UtteranceGenerator.genForObject(aContext.newAncestry[i]);
|
||||||
|
if (utter.length) {
|
||||||
|
output.push.apply(output, utter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
} else {
|
||||||
|
// Utter the entire context change in linear navigation.
|
||||||
|
aContext.newAncestry.forEach(
|
||||||
|
function(acc) {
|
||||||
|
output.push.apply(output, UtteranceGenerator.genForObject(acc));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
output.push.apply(output,
|
output.push.apply(output,
|
||||||
UtteranceGenerator.genForObject(aContext.accessible));
|
UtteranceGenerator.genForObject(aContext.accessible));
|
||||||
|
@ -253,7 +291,9 @@ AndroidPresenter.prototype = {
|
||||||
this.sendMessageToJava({
|
this.sendMessageToJava({
|
||||||
gecko: {
|
gecko: {
|
||||||
type: 'Accessibility:Event',
|
type: 'Accessibility:Event',
|
||||||
eventType: this.ANDROID_VIEW_FOCUSED,
|
eventType: isExploreByTouch ?
|
||||||
|
this.ANDROID_VIEW_HOVER_ENTER :
|
||||||
|
this.ANDROID_VIEW_FOCUSED,
|
||||||
text: output
|
text: output
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -271,7 +311,7 @@ AndroidPresenter.prototype = {
|
||||||
|
|
||||||
tabSelected: function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
|
tabSelected: function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
|
||||||
// Send a pivot change message with the full context utterance for this doc.
|
// Send a pivot change message with the full context utterance for this doc.
|
||||||
this.pivotChanged(aVCContext);
|
this.pivotChanged(aVCContext, Ci.nsIAccessiblePivot.REASON_NONE);
|
||||||
},
|
},
|
||||||
|
|
||||||
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
|
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
|
||||||
|
@ -319,6 +359,24 @@ AndroidPresenter.prototype = {
|
||||||
this.sendMessageToJava({gecko: androidEvent});
|
this.sendMessageToJava({gecko: androidEvent});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
viewportChanged: function AndroidPresenter_viewportChanged() {
|
||||||
|
if (Utils.AndroidSdkVersion < 14)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let win = Utils.getBrowserApp(this.chromeWin).selectedBrowser.contentWindow;
|
||||||
|
this.sendMessageToJava({
|
||||||
|
gecko: {
|
||||||
|
type: 'Accessibility:Event',
|
||||||
|
eventType: this.ANDROID_VIEW_SCROLLED,
|
||||||
|
text: [],
|
||||||
|
scrollX: win.scrollX,
|
||||||
|
scrollY: win.scrollY,
|
||||||
|
maxScrollX: win.scrollMaxX,
|
||||||
|
maxScrollY: win.scrollMaxY
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
sendMessageToJava: function AndroidPresenter_sendMessageTojava(aMessage) {
|
sendMessageToJava: function AndroidPresenter_sendMessageTojava(aMessage) {
|
||||||
return Cc['@mozilla.org/android/bridge;1'].
|
return Cc['@mozilla.org/android/bridge;1'].
|
||||||
getService(Ci.nsIAndroidBridge).
|
getService(Ci.nsIAndroidBridge).
|
||||||
|
|
|
@ -48,6 +48,10 @@ var Utils = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getCurrentContentDoc: function getCurrentContentDoc(aWindow) {
|
||||||
|
return this.getBrowserApp(aWindow).selectedBrowser.contentDocument;
|
||||||
|
},
|
||||||
|
|
||||||
getViewport: function getViewport(aWindow) {
|
getViewport: function getViewport(aWindow) {
|
||||||
switch (this.OS) {
|
switch (this.OS) {
|
||||||
case 'Android':
|
case 'Android':
|
||||||
|
|
|
@ -408,20 +408,54 @@ var VirtualCursorController = {
|
||||||
SINGLE_LINE_EDITABLE: 1,
|
SINGLE_LINE_EDITABLE: 1,
|
||||||
MULTI_LINE_EDITABLE: 2,
|
MULTI_LINE_EDITABLE: 2,
|
||||||
|
|
||||||
explorebytouch: false,
|
exploreByTouch: false,
|
||||||
|
|
||||||
attach: function attach(aWindow) {
|
attach: function attach(aWindow) {
|
||||||
this.chromeWin = aWindow;
|
this.chromeWin = aWindow;
|
||||||
this.chromeWin.document.addEventListener('keypress', this, true);
|
this.chromeWin.document.addEventListener('keypress', this, true);
|
||||||
|
this.chromeWin.document.addEventListener('mousemove', this, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
detach: function detach() {
|
detach: function detach() {
|
||||||
this.chromeWin.document.removeEventListener('keypress', this, true);
|
this.chromeWin.document.removeEventListener('keypress', this, true);
|
||||||
|
this.chromeWin.document.removeEventListener('mousemove', this, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleEvent: function handleEvent(aEvent) {
|
handleEvent: function VirtualCursorController_handleEvent(aEvent) {
|
||||||
let document = Utils.getBrowserApp(this.chromeWin).
|
switch (aEvent.type) {
|
||||||
selectedBrowser.contentDocument;
|
case 'keypress':
|
||||||
|
this._handleKeypress(aEvent);
|
||||||
|
break;
|
||||||
|
case 'mousemove':
|
||||||
|
this._handleMousemove(aEvent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleMousemove: function _handleMousemove(aEvent) {
|
||||||
|
// Explore by touch is disabled.
|
||||||
|
if (!this.exploreByTouch)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// On non-Android we use the shift key to simulate touch.
|
||||||
|
if (Utils.OS != 'Android' && !aEvent.shiftKey)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// We should not be calling moveToPoint more than 10 times a second.
|
||||||
|
// It is granular enough to feel natural, and it does not hammer the CPU.
|
||||||
|
if (!this._handleMousemove._lastEventTime ||
|
||||||
|
aEvent.timeStamp - this._handleMousemove._lastEventTime >= 100) {
|
||||||
|
this.moveToPoint(Utils.getCurrentContentDoc(this.chromeWin),
|
||||||
|
aEvent.screenX, aEvent.screenY);
|
||||||
|
this._handleMousemove._lastEventTime = aEvent.timeStamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
aEvent.preventDefault();
|
||||||
|
aEvent.stopImmediatePropagation();
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleKeypress: function _handleKeypress(aEvent) {
|
||||||
|
let document = Utils.getCurrentContentDoc(this.chromeWin);
|
||||||
let target = aEvent.target;
|
let target = aEvent.target;
|
||||||
|
|
||||||
switch (aEvent.keyCode) {
|
switch (aEvent.keyCode) {
|
||||||
|
@ -499,6 +533,11 @@ var VirtualCursorController = {
|
||||||
aEvent.stopPropagation();
|
aEvent.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
moveToPoint: function moveToPoint(aDocument, aX, aY) {
|
||||||
|
this.getVirtualCursor(aDocument).moveToPoint(TraversalRules.Simple,
|
||||||
|
aX, aY, true);
|
||||||
|
},
|
||||||
|
|
||||||
_isEditableText: function _isEditableText(aElement) {
|
_isEditableText: function _isEditableText(aElement) {
|
||||||
// XXX: Support contentEditable and design mode
|
// XXX: Support contentEditable and design mode
|
||||||
if (aElement instanceof Ci.nsIDOMHTMLInputElement &&
|
if (aElement instanceof Ci.nsIDOMHTMLInputElement &&
|
||||||
|
@ -582,8 +621,7 @@ var VirtualCursorController = {
|
||||||
doc = doc.parentDocument;
|
doc = doc.parentDocument;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (vc)
|
vc.moveNext(aRule || TraversalRules.Simple, aAccessible, true);
|
||||||
vc.moveNext(aRule || TraversalRules.Simple, aAccessible, true);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -103,7 +103,7 @@ __try {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == *ppv) {
|
if (NULL == *ppv) {
|
||||||
HRESULT hr = CAccessibleHyperlink::QueryInterface(iid, ppv);
|
HRESULT hr = ia2AccessibleHyperlink::QueryInterface(iid, ppv);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "Accessible.h"
|
#include "Accessible.h"
|
||||||
#include "Accessible2.h"
|
#include "Accessible2.h"
|
||||||
#include "ia2AccessibleComponent.h"
|
#include "ia2AccessibleComponent.h"
|
||||||
#include "CAccessibleHyperlink.h"
|
#include "ia2AccessibleHyperlink.h"
|
||||||
#include "CAccessibleValue.h"
|
#include "CAccessibleValue.h"
|
||||||
|
|
||||||
#define DECL_IUNKNOWN_INHERITED \
|
#define DECL_IUNKNOWN_INHERITED \
|
||||||
|
@ -65,7 +65,7 @@ Class::QueryInterface(REFIID iid, void** ppv) \
|
||||||
|
|
||||||
class AccessibleWrap : public Accessible,
|
class AccessibleWrap : public Accessible,
|
||||||
public ia2AccessibleComponent,
|
public ia2AccessibleComponent,
|
||||||
public CAccessibleHyperlink,
|
public ia2AccessibleHyperlink,
|
||||||
public CAccessibleValue,
|
public CAccessibleValue,
|
||||||
public IAccessible2
|
public IAccessible2
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,7 +26,6 @@ CPPSRCS = \
|
||||||
nsAccessNodeWrap.cpp \
|
nsAccessNodeWrap.cpp \
|
||||||
nsHTMLWin32ObjectAccessible.cpp \
|
nsHTMLWin32ObjectAccessible.cpp \
|
||||||
nsWinUtils.cpp \
|
nsWinUtils.cpp \
|
||||||
CAccessibleHyperlink.cpp \
|
|
||||||
CAccessibleTable.cpp \
|
CAccessibleTable.cpp \
|
||||||
CAccessibleTableCell.cpp \
|
CAccessibleTableCell.cpp \
|
||||||
CAccessibleValue.cpp \
|
CAccessibleValue.cpp \
|
||||||
|
@ -36,6 +35,7 @@ CPPSRCS = \
|
||||||
ia2AccessibleComponent.cpp \
|
ia2AccessibleComponent.cpp \
|
||||||
ia2AccessibleEditableText.cpp \
|
ia2AccessibleEditableText.cpp \
|
||||||
ia2AccessibleImage.cpp \
|
ia2AccessibleImage.cpp \
|
||||||
|
ia2AccessibleHyperlink.cpp \
|
||||||
ia2AccessibleHypertext.cpp \
|
ia2AccessibleHypertext.cpp \
|
||||||
ia2AccessibleRelation.cpp \
|
ia2AccessibleRelation.cpp \
|
||||||
ia2AccessibleText.cpp \
|
ia2AccessibleText.cpp \
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "CAccessibleHyperlink.h"
|
|
||||||
|
|
||||||
#include "Accessible2.h"
|
#include "Accessible2.h"
|
||||||
#include "AccessibleHyperlink.h"
|
#include "AccessibleHyperlink.h"
|
||||||
#include "AccessibleHyperlink_i.c"
|
#include "AccessibleHyperlink_i.c"
|
||||||
|
@ -17,13 +15,12 @@
|
||||||
// IUnknown
|
// IUnknown
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
CAccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
|
ia2AccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
|
||||||
{
|
{
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
|
|
||||||
if (IID_IAccessibleHyperlink == iid) {
|
if (IID_IAccessibleHyperlink == iid) {
|
||||||
nsRefPtr<Accessible> thisObj = do_QueryObject(this);
|
if (!static_cast<AccessibleWrap*>(this)->IsLink())
|
||||||
if (!thisObj->IsLink())
|
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
|
|
||||||
*ppv = static_cast<IAccessibleHyperlink*>(this);
|
*ppv = static_cast<IAccessibleHyperlink*>(this);
|
||||||
|
@ -37,12 +34,12 @@ CAccessibleHyperlink::QueryInterface(REFIID iid, void** ppv)
|
||||||
// IAccessibleHyperlink
|
// IAccessibleHyperlink
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
CAccessibleHyperlink::get_anchor(long aIndex, VARIANT *aAnchor)
|
ia2AccessibleHyperlink::get_anchor(long aIndex, VARIANT* aAnchor)
|
||||||
{
|
{
|
||||||
__try {
|
__try {
|
||||||
VariantInit(aAnchor);
|
VariantInit(aAnchor);
|
||||||
|
|
||||||
nsRefPtr<Accessible> thisObj = do_QueryObject(this);
|
Accessible* thisObj = static_cast<AccessibleWrap*>(this);
|
||||||
if (thisObj->IsDefunct())
|
if (thisObj->IsDefunct())
|
||||||
return CO_E_OBJNOTCONNECTED;
|
return CO_E_OBJNOTCONNECTED;
|
||||||
|
|
||||||
|
@ -72,12 +69,12 @@ __try {
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
CAccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT *aAnchorTarget)
|
ia2AccessibleHyperlink::get_anchorTarget(long aIndex, VARIANT* aAnchorTarget)
|
||||||
{
|
{
|
||||||
__try {
|
__try {
|
||||||
VariantInit(aAnchorTarget);
|
VariantInit(aAnchorTarget);
|
||||||
|
|
||||||
nsRefPtr<Accessible> thisObj = do_QueryObject(this);
|
Accessible* thisObj = static_cast<AccessibleWrap*>(this);
|
||||||
if (thisObj->IsDefunct())
|
if (thisObj->IsDefunct())
|
||||||
return CO_E_OBJNOTCONNECTED;
|
return CO_E_OBJNOTCONNECTED;
|
||||||
|
|
||||||
|
@ -115,12 +112,12 @@ __try {
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
CAccessibleHyperlink::get_startIndex(long *aIndex)
|
ia2AccessibleHyperlink::get_startIndex(long* aIndex)
|
||||||
{
|
{
|
||||||
__try {
|
__try {
|
||||||
*aIndex = 0;
|
*aIndex = 0;
|
||||||
|
|
||||||
nsRefPtr<Accessible> thisObj = do_QueryObject(this);
|
Accessible* thisObj = static_cast<AccessibleWrap*>(this);
|
||||||
if (thisObj->IsDefunct())
|
if (thisObj->IsDefunct())
|
||||||
return CO_E_OBJNOTCONNECTED;
|
return CO_E_OBJNOTCONNECTED;
|
||||||
|
|
||||||
|
@ -135,12 +132,12 @@ __try {
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
CAccessibleHyperlink::get_endIndex(long *aIndex)
|
ia2AccessibleHyperlink::get_endIndex(long* aIndex)
|
||||||
{
|
{
|
||||||
__try {
|
__try {
|
||||||
*aIndex = 0;
|
*aIndex = 0;
|
||||||
|
|
||||||
nsRefPtr<Accessible> thisObj = do_QueryObject(this);
|
Accessible* thisObj = static_cast<AccessibleWrap*>(this);
|
||||||
if (thisObj->IsDefunct())
|
if (thisObj->IsDefunct())
|
||||||
return CO_E_OBJNOTCONNECTED;
|
return CO_E_OBJNOTCONNECTED;
|
||||||
|
|
||||||
|
@ -155,12 +152,12 @@ __try {
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP
|
STDMETHODIMP
|
||||||
CAccessibleHyperlink::get_valid(boolean *aValid)
|
ia2AccessibleHyperlink::get_valid(boolean* aValid)
|
||||||
{
|
{
|
||||||
__try {
|
__try {
|
||||||
*aValid = false;
|
*aValid = false;
|
||||||
|
|
||||||
nsRefPtr<Accessible> thisObj = do_QueryObject(this);
|
Accessible* thisObj = static_cast<AccessibleWrap*>(this);
|
||||||
if (thisObj->IsDefunct())
|
if (thisObj->IsDefunct())
|
||||||
return CO_E_OBJNOTCONNECTED;
|
return CO_E_OBJNOTCONNECTED;
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
#include "ia2AccessibleAction.h"
|
#include "ia2AccessibleAction.h"
|
||||||
#include "AccessibleHyperlink.h"
|
#include "AccessibleHyperlink.h"
|
||||||
|
|
||||||
class CAccessibleHyperlink: public ia2AccessibleAction,
|
class ia2AccessibleHyperlink : public ia2AccessibleAction,
|
||||||
public IAccessibleHyperlink
|
public IAccessibleHyperlink
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -6,13 +6,23 @@
|
||||||
|
|
||||||
<script type="application/javascript"
|
<script type="application/javascript"
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||||
|
|
||||||
<script type="application/javascript"
|
<script type="application/javascript"
|
||||||
src="../common.js"></script>
|
src="../common.js"></script>
|
||||||
<script type="application/javascript"
|
<script type="application/javascript"
|
||||||
src="../layout.js"></script>
|
src="../layout.js"></script>
|
||||||
|
<script type="application/javascript"
|
||||||
|
src="../events.js"></script>
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
function doPreTest()
|
||||||
|
{
|
||||||
|
var imgMap = document.getElementById("imgmap");
|
||||||
|
waitForImageMap(imgMap, doTest);
|
||||||
|
}
|
||||||
|
|
||||||
function doTest()
|
function doTest()
|
||||||
{
|
{
|
||||||
// Not specific case, child and deepchild testing.
|
// Not specific case, child and deepchild testing.
|
||||||
|
@ -54,11 +64,16 @@ if (!MAC) {
|
||||||
|
|
||||||
testChildAtPoint("area", 1, 1, "area", "area");
|
testChildAtPoint("area", 1, 1, "area", "area");
|
||||||
|
|
||||||
|
// Test image maps. Their children are not in the layout tree.
|
||||||
|
var theLetterA = getAccessible("imgmap").firstChild;
|
||||||
|
hitTest("imgmap", theLetterA, theLetterA);
|
||||||
|
hitTest("container", "imgmap", theLetterA);
|
||||||
|
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
addA11yLoadEvent(doTest);
|
addA11yLoadEvent(doPreTest);
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -82,5 +97,15 @@ if (!MAC) {
|
||||||
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
|
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
|
||||||
</div>
|
</div>
|
||||||
<div id="area" style="width: 100px; height: 100px; background-color: blue;"></div>
|
<div id="area" style="width: 100px; height: 100px; background-color: blue;"></div>
|
||||||
|
|
||||||
|
<map name="atoz_map">
|
||||||
|
<area href="http://www.bbc.co.uk/radio4/atoz/index.shtml#a"
|
||||||
|
coords="0,0,15,15" alt="thelettera" shape="rect"/>
|
||||||
|
</map>
|
||||||
|
|
||||||
|
<div id="container">
|
||||||
|
<img id="imgmap" width="447" height="15" usemap="#atoz_map" src="../letters.gif"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -71,9 +71,20 @@ let FormAssistant = {
|
||||||
if (evt.target != target || this.isKeyboardOpened)
|
if (evt.target != target || this.isKeyboardOpened)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(evt.target instanceof HTMLInputElement ||
|
let ignore = {
|
||||||
evt.target instanceof HTMLTextAreaElement))
|
button: true,
|
||||||
|
checkbox: true,
|
||||||
|
file: true,
|
||||||
|
radio: true,
|
||||||
|
reset: true,
|
||||||
|
submit: true
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((target instanceof HTMLInputElement && ignore[target.type]) ||
|
||||||
|
!(target instanceof HTMLInputElement ||
|
||||||
|
target instanceof HTMLTextAreaElement)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.isKeyboardOpened = this.tryShowIme(evt.target);
|
this.isKeyboardOpened = this.tryShowIme(evt.target);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,6 +18,8 @@ window.addEventListener('ContentStart', function() {
|
||||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||||
let hostDPI = windowUtils.displayDPI;
|
let hostDPI = windowUtils.displayDPI;
|
||||||
|
|
||||||
|
let DEFAULT_SCREEN = "320x480";
|
||||||
|
|
||||||
// This is a somewhat random selection of named screens.
|
// This is a somewhat random selection of named screens.
|
||||||
// Add more to this list when we support more hardware.
|
// Add more to this list when we support more hardware.
|
||||||
// Data from: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
|
// Data from: http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
|
||||||
|
@ -62,9 +64,9 @@ window.addEventListener('ContentStart', function() {
|
||||||
try {
|
try {
|
||||||
screenarg = args.handleFlagWithParam('screen', false);
|
screenarg = args.handleFlagWithParam('screen', false);
|
||||||
|
|
||||||
// If there isn't one, we don't need to do anything
|
// If there isn't one, use the default screen
|
||||||
if (screenarg === null)
|
if (screenarg === null)
|
||||||
return;
|
screenarg = DEFAULT_SCREEN;
|
||||||
|
|
||||||
// With no value, tell the user how to use it
|
// With no value, tell the user how to use it
|
||||||
if (screenarg == '')
|
if (screenarg == '')
|
||||||
|
|
|
@ -140,7 +140,6 @@ var shell = {
|
||||||
addPermissions(domains.split(","));
|
addPermissions(domains.split(","));
|
||||||
|
|
||||||
CustomEventManager.init();
|
CustomEventManager.init();
|
||||||
|
|
||||||
WebappsHelper.init();
|
WebappsHelper.init();
|
||||||
|
|
||||||
// XXX could factor out into a settings->pref map. Not worth it yet.
|
// XXX could factor out into a settings->pref map. Not worth it yet.
|
||||||
|
@ -216,7 +215,7 @@ var shell = {
|
||||||
case evt.DOM_VK_PAGE_DOWN:
|
case evt.DOM_VK_PAGE_DOWN:
|
||||||
this.changeVolume(-1);
|
this.changeVolume(-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case evt.DOM_VK_PAGE_UP:
|
case evt.DOM_VK_PAGE_UP:
|
||||||
this.changeVolume(1);
|
this.changeVolume(1);
|
||||||
break;
|
break;
|
||||||
|
@ -249,6 +248,9 @@ var shell = {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'mozbrowserloadstart':
|
case 'mozbrowserloadstart':
|
||||||
|
if (content.document.location == 'about:blank')
|
||||||
|
return;
|
||||||
|
|
||||||
this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
|
this.contentBrowser.removeEventListener('mozbrowserloadstart', this, true);
|
||||||
|
|
||||||
let chromeWindow = window.QueryInterface(Ci.nsIDOMChromeWindow);
|
let chromeWindow = window.QueryInterface(Ci.nsIDOMChromeWindow);
|
||||||
|
|
|
@ -187,6 +187,7 @@
|
||||||
command="Tools:Scratchpad"/>
|
command="Tools:Scratchpad"/>
|
||||||
<menuitem id="appmenu_styleeditor"
|
<menuitem id="appmenu_styleeditor"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
|
type="checkbox"
|
||||||
label="&styleeditor.label;"
|
label="&styleeditor.label;"
|
||||||
key="key_styleeditor"
|
key="key_styleeditor"
|
||||||
command="Tools:StyleEditor"/>
|
command="Tools:StyleEditor"/>
|
||||||
|
|
|
@ -563,6 +563,7 @@
|
||||||
key="key_scratchpad"
|
key="key_scratchpad"
|
||||||
command="Tools:Scratchpad"/>
|
command="Tools:Scratchpad"/>
|
||||||
<menuitem id="menu_styleeditor"
|
<menuitem id="menu_styleeditor"
|
||||||
|
type="checkbox"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
label="&styleeditor.label;"
|
label="&styleeditor.label;"
|
||||||
accesskey="&styleeditor.accesskey;"
|
accesskey="&styleeditor.accesskey;"
|
||||||
|
|
|
@ -95,7 +95,7 @@
|
||||||
<command id="Tools:RemoteDebugger" oncommand="DebuggerUI.toggleRemoteDebugger();" disabled="true"/>
|
<command id="Tools:RemoteDebugger" oncommand="DebuggerUI.toggleRemoteDebugger();" disabled="true"/>
|
||||||
<command id="Tools:ChromeDebugger" oncommand="DebuggerUI.toggleChromeDebugger();" disabled="true"/>
|
<command id="Tools:ChromeDebugger" oncommand="DebuggerUI.toggleChromeDebugger();" disabled="true"/>
|
||||||
<command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true"/>
|
<command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true"/>
|
||||||
<command id="Tools:StyleEditor" oncommand="StyleEditor.openChrome();" disabled="true"/>
|
<command id="Tools:StyleEditor" oncommand="StyleEditor.toggle();" disabled="true"/>
|
||||||
<command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true"/>
|
<command id="Tools:ResponsiveUI" oncommand="ResponsiveUI.toggle();" disabled="true"/>
|
||||||
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
|
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
|
||||||
<command id="Tools:Sanitize"
|
<command id="Tools:Sanitize"
|
||||||
|
|
|
@ -1477,6 +1477,7 @@ var gBrowserInit = {
|
||||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
document.getElementById("appmenu_styleeditor").hidden = false;
|
document.getElementById("appmenu_styleeditor").hidden = false;
|
||||||
#endif
|
#endif
|
||||||
|
document.getElementById("developer-toolbar-styleeditor").hidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
|
@ -1496,7 +1497,6 @@ var gBrowserInit = {
|
||||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
document.getElementById("appmenu_responsiveUI").hidden = false;
|
document.getElementById("appmenu_responsiveUI").hidden = false;
|
||||||
#endif
|
#endif
|
||||||
document.getElementById("developer-toolbar-responsiveui").hidden = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let appMenuButton = document.getElementById("appmenu-button");
|
let appMenuButton = document.getElementById("appmenu-button");
|
||||||
|
@ -7370,40 +7370,29 @@ var StyleEditor = {
|
||||||
*/
|
*/
|
||||||
openChrome: function SE_openChrome(aSelectedStyleSheet, aLine, aCol)
|
openChrome: function SE_openChrome(aSelectedStyleSheet, aLine, aCol)
|
||||||
{
|
{
|
||||||
const CHROME_URL = "chrome://browser/content/styleeditor.xul";
|
|
||||||
const CHROME_WINDOW_TYPE = "Tools:StyleEditor";
|
|
||||||
const CHROME_WINDOW_FLAGS = "chrome,centerscreen,resizable,dialog=no";
|
|
||||||
|
|
||||||
// focus currently open Style Editor window for this document, if any
|
|
||||||
let contentWindow = gBrowser.selectedBrowser.contentWindow;
|
let contentWindow = gBrowser.selectedBrowser.contentWindow;
|
||||||
let contentWindowID = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
let win = this.StyleEditorManager.getEditorForWindow(contentWindow);
|
||||||
getInterface(Ci.nsIDOMWindowUtils).currentInnerWindowID;
|
if (win) {
|
||||||
let enumerator = Services.wm.getEnumerator(CHROME_WINDOW_TYPE);
|
this.StyleEditorManager.selectEditor(win);
|
||||||
while (enumerator.hasMoreElements()) {
|
return win;
|
||||||
var win = enumerator.getNext();
|
} else {
|
||||||
if (win.styleEditorChrome.contentWindowID == contentWindowID) {
|
return this.StyleEditorManager.newEditor(contentWindow,
|
||||||
if (aSelectedStyleSheet) {
|
aSelectedStyleSheet, aLine, aCol);
|
||||||
win.styleEditorChrome.selectStyleSheet(aSelectedStyleSheet, aLine, aCol);
|
|
||||||
}
|
|
||||||
win.focus();
|
|
||||||
return win;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
let args = {
|
toggle: function SE_toggle()
|
||||||
contentWindow: contentWindow,
|
{
|
||||||
selectedStyleSheet: aSelectedStyleSheet,
|
this.StyleEditorManager.toggleEditor(gBrowser.contentWindow);
|
||||||
line: aLine,
|
|
||||||
col: aCol
|
|
||||||
};
|
|
||||||
args.wrappedJSObject = args;
|
|
||||||
let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank",
|
|
||||||
CHROME_WINDOW_FLAGS, args);
|
|
||||||
chromeWindow.focus();
|
|
||||||
return chromeWindow;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(StyleEditor, "StyleEditorManager", function() {
|
||||||
|
let tmp = {};
|
||||||
|
Cu.import("resource:///modules/devtools/StyleEditor.jsm", tmp);
|
||||||
|
return new tmp.StyleEditorManager(window);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
|
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
|
|
|
@ -1045,13 +1045,13 @@
|
||||||
class="devtools-toolbarbutton"
|
class="devtools-toolbarbutton"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
command="Tools:Inspect"/>
|
command="Tools:Inspect"/>
|
||||||
<toolbarbutton id="developer-toolbar-responsiveui"
|
<toolbarbutton id="developer-toolbar-styleeditor"
|
||||||
label="&responsiveDesignTool.label;"
|
label="&styleeditor.label;"
|
||||||
class="devtools-toolbarbutton"
|
class="devtools-toolbarbutton"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
command="Tools:ResponsiveUI"/>
|
command="Tools:StyleEditor"/>
|
||||||
<toolbarbutton id="developer-toolbar-debugger"
|
<toolbarbutton id="developer-toolbar-debugger"
|
||||||
label="&scriptsButton.label;"
|
label="&debuggerMenu.label2;"
|
||||||
class="devtools-toolbarbutton"
|
class="devtools-toolbarbutton"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
command="Tools:Debugger"/>
|
command="Tools:Debugger"/>
|
||||||
|
|
|
@ -2,10 +2,6 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
:root {
|
|
||||||
-moz-user-focus: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=button] {
|
input[type=button] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +11,7 @@ input[type=button] {
|
||||||
display: -moz-box;
|
display: -moz-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
-moz-box-flex: 1;
|
-moz-box-flex: 1;
|
||||||
|
-moz-user-focus: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
#newtab-scrollbox:not([page-disabled]) {
|
#newtab-scrollbox:not([page-disabled]) {
|
||||||
|
|
|
@ -80,18 +80,24 @@ let gPage = {
|
||||||
* @param aValue Whether the New Tab Page is enabled or not.
|
* @param aValue Whether the New Tab Page is enabled or not.
|
||||||
*/
|
*/
|
||||||
_updateAttributes: function Page_updateAttributes(aValue) {
|
_updateAttributes: function Page_updateAttributes(aValue) {
|
||||||
let selector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid";
|
|
||||||
let nodes = document.querySelectorAll(selector);
|
|
||||||
|
|
||||||
// Set the nodes' states.
|
// Set the nodes' states.
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
let nodeSelector = "#newtab-scrollbox, #newtab-toggle, #newtab-grid";
|
||||||
let node = nodes[i];
|
for (let node of document.querySelectorAll(nodeSelector)) {
|
||||||
if (aValue)
|
if (aValue)
|
||||||
node.removeAttribute("page-disabled");
|
node.removeAttribute("page-disabled");
|
||||||
else
|
else
|
||||||
node.setAttribute("page-disabled", "true");
|
node.setAttribute("page-disabled", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enables/disables the control and link elements.
|
||||||
|
let inputSelector = ".newtab-control, .newtab-link";
|
||||||
|
for (let input of document.querySelectorAll(inputSelector)) {
|
||||||
|
if (aValue)
|
||||||
|
input.removeAttribute("tabindex");
|
||||||
|
else
|
||||||
|
input.setAttribute("tabindex", "-1");
|
||||||
|
}
|
||||||
|
|
||||||
// Update the toggle button's title.
|
// Update the toggle button's title.
|
||||||
let toggle = document.getElementById("newtab-toggle");
|
let toggle = document.getElementById("newtab-toggle");
|
||||||
toggle.setAttribute("title", newTabString(aValue ? "hide" : "show"));
|
toggle.setAttribute("title", newTabString(aValue ? "hide" : "show"));
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"size": 47,
|
||||||
|
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
|
||||||
|
"algorithm": "sha512",
|
||||||
|
"filename": "setup.sh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 72350187,
|
||||||
|
"digest": "7d2fbe08aca3ae740e33b8aee872705a3b5229681dd0617ceffd6619fba75cb3cb7e1c3a071218f7cfd464003e5cd773cd8e67d16f78df9c50218fb6671580c6",
|
||||||
|
"algorithm": "sha512",
|
||||||
|
"filename": "clang.tar.bz2"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"size": 47,
|
||||||
|
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
|
||||||
|
"algorithm": "sha512",
|
||||||
|
"filename": "setup.sh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 71534797,
|
||||||
|
"digest": "66bd11bea6e1f07090e9e03c833e107088097605611fd455e80b280ce2b71ca71ff9841a66614f62da162469b222b5eefd5535373b199c60fd485959889b5dcb",
|
||||||
|
"algorithm": "sha512",
|
||||||
|
"filename": "clang.tar.bz2"
|
||||||
|
}
|
||||||
|
]
|
|
@ -0,0 +1 @@
|
||||||
|
../macosx64/clang.manifest
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"size": 47,
|
||||||
|
"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa",
|
||||||
|
"algorithm": "sha512",
|
||||||
|
"filename": "setup.sh"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size": 63015959,
|
||||||
|
"digest": "e0ac132a77b052d6494d4bf02f17aba475138ffcff07a5f92f17f45b1d5f27b7b0cea36c29473965271e60910af82ffd4989df94c10d24794d1bf8362bcb785b",
|
||||||
|
"algorithm": "sha512",
|
||||||
|
"filename": "clang.tar.bz2"
|
||||||
|
}
|
||||||
|
]
|
|
@ -35,6 +35,7 @@ function checkOpen() {
|
||||||
let close = document.getElementById("developer-toolbar-closebutton");
|
let close = document.getElementById("developer-toolbar-closebutton");
|
||||||
let webconsole = document.getElementById("developer-toolbar-webconsole");
|
let webconsole = document.getElementById("developer-toolbar-webconsole");
|
||||||
let inspector = document.getElementById("developer-toolbar-inspector");
|
let inspector = document.getElementById("developer-toolbar-inspector");
|
||||||
|
let styleeditor = document.getElementById("developer-toolbar-styleeditor");
|
||||||
let debuggr = document.getElementById("developer-toolbar-debugger");
|
let debuggr = document.getElementById("developer-toolbar-debugger");
|
||||||
|
|
||||||
ok(close, "Close button exists");
|
ok(close, "Close button exists");
|
||||||
|
@ -42,18 +43,21 @@ function checkOpen() {
|
||||||
ok(!isChecked(webconsole), "web console button state 1");
|
ok(!isChecked(webconsole), "web console button state 1");
|
||||||
ok(!isChecked(inspector), "inspector button state 1");
|
ok(!isChecked(inspector), "inspector button state 1");
|
||||||
ok(!isChecked(debuggr), "debugger button state 1");
|
ok(!isChecked(debuggr), "debugger button state 1");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 1");
|
||||||
|
|
||||||
document.getElementById("Tools:WebConsole").doCommand();
|
document.getElementById("Tools:WebConsole").doCommand();
|
||||||
|
|
||||||
ok(isChecked(webconsole), "web console button state 2");
|
ok(isChecked(webconsole), "web console button state 2");
|
||||||
ok(!isChecked(inspector), "inspector button state 2");
|
ok(!isChecked(inspector), "inspector button state 2");
|
||||||
ok(!isChecked(debuggr), "debugger button state 2");
|
ok(!isChecked(debuggr), "debugger button state 2");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 2");
|
||||||
|
|
||||||
document.getElementById("Tools:Inspect").doCommand();
|
document.getElementById("Tools:Inspect").doCommand();
|
||||||
|
|
||||||
ok(isChecked(webconsole), "web console button state 3");
|
ok(isChecked(webconsole), "web console button state 3");
|
||||||
ok(isChecked(inspector), "inspector button state 3");
|
ok(isChecked(inspector), "inspector button state 3");
|
||||||
ok(!isChecked(debuggr), "debugger button state 3");
|
ok(!isChecked(debuggr), "debugger button state 3");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 3");
|
||||||
|
|
||||||
// Christmas tree!
|
// Christmas tree!
|
||||||
|
|
||||||
|
@ -66,12 +70,14 @@ function checkOpen() {
|
||||||
ok(!isChecked(webconsole), "web console button state 6");
|
ok(!isChecked(webconsole), "web console button state 6");
|
||||||
ok(isChecked(inspector), "inspector button state 6");
|
ok(isChecked(inspector), "inspector button state 6");
|
||||||
ok(!isChecked(debuggr), "debugger button state 6");
|
ok(!isChecked(debuggr), "debugger button state 6");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 6");
|
||||||
|
|
||||||
document.getElementById("Tools:Inspect").doCommand();
|
document.getElementById("Tools:Inspect").doCommand();
|
||||||
|
|
||||||
ok(!isChecked(webconsole), "web console button state 7");
|
ok(!isChecked(webconsole), "web console button state 7");
|
||||||
ok(!isChecked(inspector), "inspector button state 7");
|
ok(!isChecked(inspector), "inspector button state 7");
|
||||||
ok(!isChecked(debuggr), "debugger button state 7");
|
ok(!isChecked(debuggr), "debugger button state 7");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 7");
|
||||||
|
|
||||||
// All closed
|
// All closed
|
||||||
|
|
||||||
|
@ -81,9 +87,38 @@ function checkOpen() {
|
||||||
ok(!isChecked(webconsole), "web console button state 8");
|
ok(!isChecked(webconsole), "web console button state 8");
|
||||||
ok(isChecked(inspector), "inspector button state 8");
|
ok(isChecked(inspector), "inspector button state 8");
|
||||||
ok(!isChecked(debuggr), "debugger button state 8");
|
ok(!isChecked(debuggr), "debugger button state 8");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 8");
|
||||||
|
|
||||||
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.HIDE, catchFail(checkClosed));
|
|
||||||
document.getElementById("Tools:DevToolbar").doCommand();
|
// Test Style Editor
|
||||||
|
document.getElementById("Tools:StyleEditor").doCommand();
|
||||||
|
|
||||||
|
ok(!isChecked(webconsole), "web console button state 9");
|
||||||
|
ok(isChecked(inspector), "inspector button state 9");
|
||||||
|
ok(!isChecked(debuggr), "debugger button state 9");
|
||||||
|
ok(isChecked(styleeditor), "styleeditor button state 9");
|
||||||
|
|
||||||
|
// Test Debugger
|
||||||
|
document.getElementById("Tools:Debugger").doCommand();
|
||||||
|
|
||||||
|
ok(!isChecked(webconsole), "web console button state 9");
|
||||||
|
ok(isChecked(inspector), "inspector button state 9");
|
||||||
|
ok(isChecked(debuggr), "debugger button state 9");
|
||||||
|
ok(isChecked(styleeditor), "styleeditor button state 9");
|
||||||
|
|
||||||
|
addTab("about:blank", function(browser, tab) {
|
||||||
|
info("Opening a new tab");
|
||||||
|
|
||||||
|
ok(!isChecked(webconsole), "web console button state 10");
|
||||||
|
ok(!isChecked(inspector), "inspector button state 10");
|
||||||
|
ok(!isChecked(debuggr), "debugger button state 10");
|
||||||
|
ok(!isChecked(styleeditor), "styleeditor button state 10");
|
||||||
|
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
|
||||||
|
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.HIDE, catchFail(checkClosed));
|
||||||
|
document.getElementById("Tools:DevToolbar").doCommand();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkClosed() {
|
function checkClosed() {
|
||||||
|
@ -102,10 +137,15 @@ function checkReOpen() {
|
||||||
let webconsole = document.getElementById("developer-toolbar-webconsole");
|
let webconsole = document.getElementById("developer-toolbar-webconsole");
|
||||||
let inspector = document.getElementById("developer-toolbar-inspector");
|
let inspector = document.getElementById("developer-toolbar-inspector");
|
||||||
let debuggr = document.getElementById("developer-toolbar-debugger");
|
let debuggr = document.getElementById("developer-toolbar-debugger");
|
||||||
|
let styleeditor = document.getElementById("developer-toolbar-styleeditor");
|
||||||
|
|
||||||
ok(isChecked(webconsole), "web console button state 9");
|
ok(isChecked(webconsole), "web console button state 99");
|
||||||
ok(isChecked(inspector), "inspector button state 9");
|
ok(isChecked(inspector), "inspector button state 99");
|
||||||
ok(!isChecked(debuggr), "debugger button state 9");
|
ok(isChecked(debuggr), "debugger button state 99");
|
||||||
|
ok(isChecked(styleeditor), "styleeditor button state 99");
|
||||||
|
|
||||||
|
// We close the style editor (not automatically closed)
|
||||||
|
document.getElementById("Tools:StyleEditor").doCommand();
|
||||||
|
|
||||||
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.HIDE, catchFail(checkReClosed));
|
oneTimeObserve(DeveloperToolbar.NOTIFICATIONS.HIDE, catchFail(checkReClosed));
|
||||||
document.getElementById("developer-toolbar-closebutton").doCommand();
|
document.getElementById("developer-toolbar-closebutton").doCommand();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const EXPORTED_SYMBOLS = ["StyleEditor", "StyleEditorFlags"];
|
const EXPORTED_SYMBOLS = ["StyleEditor", "StyleEditorFlags", "StyleEditorManager"];
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const Cc = Components.classes;
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
|
@ -1160,3 +1160,133 @@ function setupBracketCompletion(aSourceEditor)
|
||||||
aSourceEditor.setCaretOffset(aSourceEditor.getCaretOffset() - 1);
|
aSourceEditor.setCaretOffset(aSourceEditor.getCaretOffset() - 1);
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage the different editors instances.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function StyleEditorManager(aWindow) {
|
||||||
|
this.chromeWindow = aWindow;
|
||||||
|
this.listenToTabs();
|
||||||
|
this.editors = new WeakMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleEditorManager.prototype = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the editor for a specific content window.
|
||||||
|
*/
|
||||||
|
getEditorForWindow: function SEM_getEditorForWindow(aContentWindow) {
|
||||||
|
return this.editors.get(aContentWindow);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Focus the editor and select a stylesheet.
|
||||||
|
*
|
||||||
|
* @param {CSSStyleSheet} [aSelectedStyleSheet] default Stylesheet.
|
||||||
|
* @param {Number} [aLine] Line to which the caret should be moved (one-indexed).
|
||||||
|
* @param {Number} [aCol] Column to which the caret should be moved (one-indexed).
|
||||||
|
*/
|
||||||
|
selectEditor: function SEM_selectEditor(aWindow, aSelectedStyleSheet, aLine, aCol) {
|
||||||
|
if (aSelectedStyleSheet) {
|
||||||
|
aWindow.styleEditorChrome.selectStyleSheet(aSelectedStyleSheet, aLine, aCol);
|
||||||
|
}
|
||||||
|
aWindow.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a new editor.
|
||||||
|
*
|
||||||
|
* @param {Window} content window.
|
||||||
|
* @param {CSSStyleSheet} [aSelectedStyleSheet] default Stylesheet.
|
||||||
|
* @param {Number} [aLine] Line to which the caret should be moved (one-indexed).
|
||||||
|
* @param {Number} [aCol] Column to which the caret should be moved (one-indexed).
|
||||||
|
*/
|
||||||
|
newEditor: function SEM_newEditor(aContentWindow, aSelectedStyleSheet, aLine, aCol) {
|
||||||
|
const CHROME_URL = "chrome://browser/content/styleeditor.xul";
|
||||||
|
const CHROME_WINDOW_FLAGS = "chrome,centerscreen,resizable,dialog=no";
|
||||||
|
|
||||||
|
let args = {
|
||||||
|
contentWindow: aContentWindow,
|
||||||
|
selectedStyleSheet: aSelectedStyleSheet,
|
||||||
|
line: aLine,
|
||||||
|
col: aCol
|
||||||
|
};
|
||||||
|
args.wrappedJSObject = args;
|
||||||
|
let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank",
|
||||||
|
CHROME_WINDOW_FLAGS, args);
|
||||||
|
|
||||||
|
chromeWindow.onunload = function() {
|
||||||
|
if (chromeWindow.location == CHROME_URL) {
|
||||||
|
// not about:blank being unloaded
|
||||||
|
this.unregisterEditor(aContentWindow);
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
chromeWindow.focus();
|
||||||
|
|
||||||
|
this.editors.set(aContentWindow, chromeWindow);
|
||||||
|
|
||||||
|
this.refreshCommand();
|
||||||
|
|
||||||
|
return chromeWindow;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggle an editor.
|
||||||
|
*
|
||||||
|
* @param {Window} associated content window.
|
||||||
|
*/
|
||||||
|
toggleEditor: function SEM_toggleEditor(aContentWindow) {
|
||||||
|
let editor = this.getEditorForWindow(aContentWindow);
|
||||||
|
if (editor) {
|
||||||
|
editor.close();
|
||||||
|
} else {
|
||||||
|
this.newEditor(aContentWindow);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close an editor.
|
||||||
|
*
|
||||||
|
* @param {Window} associated content window.
|
||||||
|
*/
|
||||||
|
unregisterEditor: function SEM_unregisterEditor(aContentWindow) {
|
||||||
|
let chromeWindow = this.editors.get(aContentWindow);
|
||||||
|
if (chromeWindow) {
|
||||||
|
chromeWindow.close();
|
||||||
|
}
|
||||||
|
this.editors.delete(aContentWindow);
|
||||||
|
this.refreshCommand();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the status of tool's menuitems and buttons.
|
||||||
|
*/
|
||||||
|
refreshCommand: function SEM_refreshCommand() {
|
||||||
|
let contentWindow = this.chromeWindow.gBrowser.contentWindow;
|
||||||
|
let command = this.chromeWindow.document.getElementById("Tools:StyleEditor");
|
||||||
|
|
||||||
|
let win = this.getEditorForWindow(contentWindow);
|
||||||
|
if (win) {
|
||||||
|
command.setAttribute("checked", "true");
|
||||||
|
} else {
|
||||||
|
command.setAttribute("checked", "false");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger refreshCommand when needed.
|
||||||
|
*/
|
||||||
|
listenToTabs: function SEM_listenToTabs() {
|
||||||
|
let win = this.chromeWindow;
|
||||||
|
let tabs = win.gBrowser.tabContainer;
|
||||||
|
|
||||||
|
let bound_refreshCommand = this.refreshCommand.bind(this);
|
||||||
|
tabs.addEventListener("TabSelect", bound_refreshCommand, true);
|
||||||
|
|
||||||
|
win.addEventListener("unload", function onClose(aEvent) {
|
||||||
|
tabs.removeEventListener("TabSelect", bound_refreshCommand, true);
|
||||||
|
win.removeEventListener("unload", onClose, false);
|
||||||
|
}, false);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
|
@ -497,7 +497,7 @@ let Manager = {
|
||||||
NetworkResponseListener = ConsoleProgressListener = null;
|
NetworkResponseListener = ConsoleProgressListener = null;
|
||||||
|
|
||||||
XPCOMUtils = gConsoleStorage = WebConsoleUtils = l10n = JSPropertyProvider =
|
XPCOMUtils = gConsoleStorage = WebConsoleUtils = l10n = JSPropertyProvider =
|
||||||
NetworkHelper = NetUtil = activityDistributor = null;
|
null;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -242,7 +242,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
|
||||||
|
|
||||||
<!ENTITY webConsoleButton.label "Web Console">
|
<!ENTITY webConsoleButton.label "Web Console">
|
||||||
<!ENTITY inspectorButton.label "Inspector">
|
<!ENTITY inspectorButton.label "Inspector">
|
||||||
<!ENTITY scriptsButton.label "Scripts">
|
|
||||||
|
|
||||||
<!ENTITY inspectorHTMLCopyInner.label "Copy Inner HTML">
|
<!ENTITY inspectorHTMLCopyInner.label "Copy Inner HTML">
|
||||||
<!ENTITY inspectorHTMLCopyInner.accesskey "I">
|
<!ENTITY inspectorHTMLCopyInner.accesskey "I">
|
||||||
|
|
|
@ -5596,6 +5596,9 @@ if test -n "$MOZ_CUBEB"; then
|
||||||
*-mingw*)
|
*-mingw*)
|
||||||
AC_DEFINE(MOZ_CUBEB)
|
AC_DEFINE(MOZ_CUBEB)
|
||||||
;;
|
;;
|
||||||
|
*-darwin*)
|
||||||
|
AC_DEFINE(MOZ_CUBEB)
|
||||||
|
;;
|
||||||
*-openbsd*)
|
*-openbsd*)
|
||||||
AC_DEFINE(MOZ_CUBEB)
|
AC_DEFINE(MOZ_CUBEB)
|
||||||
;;
|
;;
|
||||||
|
|
|
@ -120,7 +120,7 @@ nsContentSink::nsContentSink()
|
||||||
NS_ASSERTION(mInNotification == 0, "What?");
|
NS_ASSERTION(mInNotification == 0, "What?");
|
||||||
NS_ASSERTION(!mDeferredLayoutStart, "What?");
|
NS_ASSERTION(!mDeferredLayoutStart, "What?");
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (!gContentSinkLogModuleInfo) {
|
if (!gContentSinkLogModuleInfo) {
|
||||||
gContentSinkLogModuleInfo = PR_NewLogModule("nscontentsink");
|
gContentSinkLogModuleInfo = PR_NewLogModule("nscontentsink");
|
||||||
}
|
}
|
||||||
|
@ -925,7 +925,7 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
|
||||||
// The http manifest attribute URI is equal to the manifest URI of
|
// The http manifest attribute URI is equal to the manifest URI of
|
||||||
// the cache the document was loaded from - associate the document with
|
// the cache the document was loaded from - associate the document with
|
||||||
// that cache and invoke the cache update process.
|
// that cache and invoke the cache update process.
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsCAutoString docURISpec, clientID;
|
nsCAutoString docURISpec, clientID;
|
||||||
mDocumentURI->GetAsciiSpec(docURISpec);
|
mDocumentURI->GetAsciiSpec(docURISpec);
|
||||||
aLoadApplicationCache->GetClientID(clientID);
|
aLoadApplicationCache->GetClientID(clientID);
|
||||||
|
@ -979,7 +979,7 @@ nsContentSink::SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplication
|
||||||
NS_ASSERTION(applicationCacheDocument,
|
NS_ASSERTION(applicationCacheDocument,
|
||||||
"mDocument must implement nsIApplicationCacheContainer.");
|
"mDocument must implement nsIApplicationCacheContainer.");
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsCAutoString docURISpec, clientID;
|
nsCAutoString docURISpec, clientID;
|
||||||
mDocumentURI->GetAsciiSpec(docURISpec);
|
mDocumentURI->GetAsciiSpec(docURISpec);
|
||||||
aLoadApplicationCache->GetClientID(clientID);
|
aLoadApplicationCache->GetClientID(clientID);
|
||||||
|
|
|
@ -52,7 +52,7 @@ class Loader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
extern PRLogModuleInfo* gContentSinkLogModuleInfo;
|
extern PRLogModuleInfo* gContentSinkLogModuleInfo;
|
||||||
|
|
||||||
|
|
|
@ -410,6 +410,15 @@ nsIdentifierMapEntry::RemoveNameElement(Element* aElement)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
size_t
|
||||||
|
nsIdentifierMapEntry::SizeOfExcludingThis(nsIdentifierMapEntry* aEntry,
|
||||||
|
nsMallocSizeOfFun aMallocSizeOf,
|
||||||
|
void*)
|
||||||
|
{
|
||||||
|
return aEntry->GetKey().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper structs for the content->subdoc map
|
// Helper structs for the content->subdoc map
|
||||||
|
|
||||||
class SubDocMapEntry : public PLDHashEntryHdr
|
class SubDocMapEntry : public PLDHashEntryHdr
|
||||||
|
@ -9682,7 +9691,8 @@ nsDocument::DocSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
|
||||||
mStyledLinks.SizeOfExcludingThis(NULL, aWindowSizes->mMallocSizeOf);
|
mStyledLinks.SizeOfExcludingThis(NULL, aWindowSizes->mMallocSizeOf);
|
||||||
|
|
||||||
aWindowSizes->mDOMOther +=
|
aWindowSizes->mDOMOther +=
|
||||||
mIdentifierMap.SizeOfExcludingThis(NULL, aWindowSizes->mMallocSizeOf);
|
mIdentifierMap.SizeOfExcludingThis(nsIdentifierMapEntry::SizeOfExcludingThis,
|
||||||
|
aWindowSizes->mMallocSizeOf);
|
||||||
|
|
||||||
// Measurement of the following members may be added later if DMD finds it
|
// Measurement of the following members may be added later if DMD finds it
|
||||||
// is worthwhile:
|
// is worthwhile:
|
||||||
|
|
|
@ -215,6 +215,10 @@ public:
|
||||||
ChangeCallback mKey;
|
ChangeCallback mKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static size_t SizeOfExcludingThis(nsIdentifierMapEntry* aEntry,
|
||||||
|
nsMallocSizeOfFun aMallocSizeOf,
|
||||||
|
void* aArg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
|
void FireChangeCallbacks(Element* aOldElement, Element* aNewElement,
|
||||||
bool aImageOnly = false);
|
bool aImageOnly = false);
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static PRLogModuleInfo* gSinkLogModuleInfo;
|
static PRLogModuleInfo* gSinkLogModuleInfo;
|
||||||
|
|
||||||
#define SINK_TRACE_NODE(_bit, _msg, _tag, _sp, _obj) \
|
#define SINK_TRACE_NODE(_bit, _msg, _tag, _sp, _obj) \
|
||||||
|
@ -188,7 +188,7 @@ protected:
|
||||||
already_AddRefed<nsGenericHTMLElement>
|
already_AddRefed<nsGenericHTMLElement>
|
||||||
CreateContentObject(const nsIParserNode& aNode, nsHTMLTag aNodeType);
|
CreateContentObject(const nsIParserNode& aNode, nsHTMLTag aNodeType);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
void SinkTraceNode(PRUint32 aBit,
|
void SinkTraceNode(PRUint32 aBit,
|
||||||
const char* aMsg,
|
const char* aMsg,
|
||||||
const nsHTMLTag aTag,
|
const nsHTMLTag aTag,
|
||||||
|
@ -243,7 +243,7 @@ protected:
|
||||||
|
|
||||||
bool IsMonolithicContainer(nsHTMLTag aTag);
|
bool IsMonolithicContainer(nsHTMLTag aTag);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
void ForceReflow();
|
void ForceReflow();
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -313,7 +313,7 @@ private:
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
HTMLContentSink::SinkTraceNode(PRUint32 aBit,
|
HTMLContentSink::SinkTraceNode(PRUint32 aBit,
|
||||||
const char* aMsg,
|
const char* aMsg,
|
||||||
|
@ -582,7 +582,7 @@ SinkContext::DidAddContent(nsIContent* aContent)
|
||||||
mStack[mStackPos - 1].mContent->GetChildCount()) {
|
mStack[mStackPos - 1].mContent->GetChildCount()) {
|
||||||
nsIContent* parent = mStack[mStackPos - 1].mContent;
|
nsIContent* parent = mStack[mStackPos - 1].mContent;
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
// Tracing code
|
// Tracing code
|
||||||
nsIParserService *parserService = nsContentUtils::GetParserService();
|
nsIParserService *parserService = nsContentUtils::GetParserService();
|
||||||
if (parserService) {
|
if (parserService) {
|
||||||
|
@ -757,7 +757,7 @@ SinkContext::CloseContainer(const nsHTMLTag aTag)
|
||||||
// notification
|
// notification
|
||||||
|
|
||||||
if (mStack[mStackPos].mNumFlushed < content->GetChildCount()) {
|
if (mStack[mStackPos].mNumFlushed < content->GetChildCount()) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
// Tracing code
|
// Tracing code
|
||||||
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
||||||
|
@ -1068,7 +1068,7 @@ SinkContext::FlushTags()
|
||||||
childCount = content->GetChildCount();
|
childCount = content->GetChildCount();
|
||||||
|
|
||||||
if (!flushed && (mStack[stackPos].mNumFlushed < childCount)) {
|
if (!flushed && (mStack[stackPos].mNumFlushed < childCount)) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
// Tracing code
|
// Tracing code
|
||||||
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
||||||
|
@ -1242,7 +1242,7 @@ HTMLContentSink::HTMLContentSink()
|
||||||
// Note: operator new zeros our memory
|
// Note: operator new zeros our memory
|
||||||
|
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (!gSinkLogModuleInfo) {
|
if (!gSinkLogModuleInfo) {
|
||||||
gSinkLogModuleInfo = PR_NewLogModule("htmlcontentsink");
|
gSinkLogModuleInfo = PR_NewLogModule("htmlcontentsink");
|
||||||
}
|
}
|
||||||
|
@ -1426,7 +1426,7 @@ HTMLContentSink::Init(nsIDocument* aDoc,
|
||||||
mCurrentContext->Begin(eHTMLTag_html, mRoot, 0, -1);
|
mCurrentContext->Begin(eHTMLTag_html, mRoot, 0, -1);
|
||||||
mContextStack.AppendElement(mCurrentContext);
|
mContextStack.AppendElement(mCurrentContext);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsCAutoString spec;
|
nsCAutoString spec;
|
||||||
(void)aURI->GetSpec(spec);
|
(void)aURI->GetSpec(spec);
|
||||||
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_CALLS,
|
SINK_TRACE(gSinkLogModuleInfo, SINK_TRACE_CALLS,
|
||||||
|
|
|
@ -2873,8 +2873,8 @@ static const struct MidasCommand gMidasCommandTable[] = {
|
||||||
{ "cut", "cmd_cut", "", true, false },
|
{ "cut", "cmd_cut", "", true, false },
|
||||||
{ "copy", "cmd_copy", "", true, false },
|
{ "copy", "cmd_copy", "", true, false },
|
||||||
{ "paste", "cmd_paste", "", true, false },
|
{ "paste", "cmd_paste", "", true, false },
|
||||||
{ "delete", "cmd_delete", "", true, false },
|
{ "delete", "cmd_deleteCharBackward", "", true, false },
|
||||||
{ "forwarddelete", "cmd_forwardDelete", "", true, false },
|
{ "forwarddelete", "cmd_deleteCharForward", "", true, false },
|
||||||
{ "selectall", "cmd_selectAll", "", true, false },
|
{ "selectall", "cmd_selectAll", "", true, false },
|
||||||
{ "undo", "cmd_undo", "", true, false },
|
{ "undo", "cmd_undo", "", true, false },
|
||||||
{ "redo", "cmd_redo", "", true, false },
|
{ "redo", "cmd_redo", "", true, false },
|
||||||
|
@ -3189,6 +3189,13 @@ nsHTMLDocument::ExecCommand(const nsAString& commandID,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return false for disabled commands (bug 760052)
|
||||||
|
bool enabled = false;
|
||||||
|
cmdMgr->IsCommandEnabled(cmdToDispatch.get(), window, &enabled);
|
||||||
|
if (!enabled) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isBool && paramStr.IsEmpty()) {
|
if (!isBool && paramStr.IsEmpty()) {
|
||||||
rv = cmdMgr->DoCommand(cmdToDispatch.get(), nsnull, window);
|
rv = cmdMgr->DoCommand(cmdToDispatch.get(), nsnull, window);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1214,7 +1214,7 @@ nsXMLContentSink::HandleDoctypeDecl(const nsAString & aSubset,
|
||||||
nsRefPtr<nsCSSStyleSheet> sheet;
|
nsRefPtr<nsCSSStyleSheet> sheet;
|
||||||
mCSSLoader->LoadSheetSync(uri, true, true, getter_AddRefs(sheet));
|
mCSSLoader->LoadSheetSync(uri, true, true, getter_AddRefs(sheet));
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsCAutoString uriStr;
|
nsCAutoString uriStr;
|
||||||
uri->GetSpec(uriStr);
|
uri->GetSpec(uriStr);
|
||||||
printf("Loading catalog stylesheet: %s ... %s\n", uriStr.get(), sheet.get() ? "Done" : "Failed");
|
printf("Loading catalog stylesheet: %s ... %s\n", uriStr.get(), sheet.get() ? "Done" : "Failed");
|
||||||
|
|
|
@ -271,7 +271,7 @@ nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
|
||||||
while (updater) {
|
while (updater) {
|
||||||
if (updater->mElement == aElement) {
|
if (updater->mElement == aElement) {
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
||||||
nsCAutoString eventsC, targetsC, aeventsC, atargetsC;
|
nsCAutoString eventsC, targetsC, aeventsC, atargetsC;
|
||||||
eventsC.AssignWithConversion(updater->mEvents);
|
eventsC.AssignWithConversion(updater->mEvents);
|
||||||
|
@ -299,7 +299,7 @@ nsXULCommandDispatcher::AddCommandUpdater(nsIDOMElement* aElement,
|
||||||
link = &(updater->mNext);
|
link = &(updater->mNext);
|
||||||
updater = updater->mNext;
|
updater = updater->mNext;
|
||||||
}
|
}
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
||||||
nsCAutoString aeventsC, atargetsC;
|
nsCAutoString aeventsC, atargetsC;
|
||||||
CopyUTF16toUTF8(aEvents, aeventsC);
|
CopyUTF16toUTF8(aEvents, aeventsC);
|
||||||
|
@ -334,7 +334,7 @@ nsXULCommandDispatcher::RemoveCommandUpdater(nsIDOMElement* aElement)
|
||||||
|
|
||||||
while (updater) {
|
while (updater) {
|
||||||
if (updater->mElement == aElement) {
|
if (updater->mElement == aElement) {
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
||||||
nsCAutoString eventsC, targetsC;
|
nsCAutoString eventsC, targetsC;
|
||||||
eventsC.AssignWithConversion(updater->mEvents);
|
eventsC.AssignWithConversion(updater->mEvents);
|
||||||
|
@ -400,7 +400,7 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
||||||
if (! document)
|
if (! document)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
if (PR_LOG_TEST(gLog, PR_LOG_NOTICE)) {
|
||||||
nsCAutoString aeventnameC;
|
nsCAutoString aeventnameC;
|
||||||
CopyUTF16toUTF8(aEventName, aeventnameC);
|
CopyUTF16toUTF8(aEventName, aeventnameC);
|
||||||
|
|
|
@ -10575,7 +10575,7 @@ nsDocShell::SetHistoryEntry(nsCOMPtr<nsISHEntry> *aPtr, nsISHEntry *aEntry)
|
||||||
nsDocShell *rootDocShell = static_cast<nsDocShell*>
|
nsDocShell *rootDocShell = static_cast<nsDocShell*>
|
||||||
(rootIDocShell);
|
(rootIDocShell);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
#endif
|
#endif
|
||||||
SetChildHistoryEntry(oldRootEntry, rootDocShell,
|
SetChildHistoryEntry(oldRootEntry, rootDocShell,
|
||||||
|
|
|
@ -613,7 +613,7 @@ static const char kDOMStringBundleURL[] =
|
||||||
(nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT)
|
(nsIClassInfo::MAIN_THREAD_ONLY | nsIClassInfo::DOM_OBJECT)
|
||||||
|
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
#define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
|
#define NS_DEFINE_CLASSINFO_DATA_DEBUG(_class) \
|
||||||
eDOMClassInfo_##_class##_id,
|
eDOMClassInfo_##_class##_id,
|
||||||
#else
|
#else
|
||||||
|
@ -4535,7 +4535,7 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLockedFile)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMLockedFile)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
PRUint32 i = ArrayLength(sClassInfoData);
|
PRUint32 i = ArrayLength(sClassInfoData);
|
||||||
|
|
||||||
|
@ -5876,7 +5876,7 @@ DefineInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
NS_ERROR("Non-numeric constant found in interface.");
|
NS_ERROR("Non-numeric constant found in interface.");
|
||||||
#endif
|
#endif
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct nsDOMClassInfoData
|
||||||
PRUint32 mInterfacesBitmap;
|
PRUint32 mInterfacesBitmap;
|
||||||
bool mChromeOnly;
|
bool mChromeOnly;
|
||||||
bool mDisabled;
|
bool mDisabled;
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
PRUint32 mDebugID;
|
PRUint32 mDebugID;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -257,7 +257,7 @@ static TimeStamp gLastRecordedRecentTimeouts;
|
||||||
PRInt32 gTimeoutCnt = 0;
|
PRInt32 gTimeoutCnt = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||||
static bool gDOMWindowDumpEnabled = false;
|
static bool gDOMWindowDumpEnabled = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -713,7 +713,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||||
gRefCnt++;
|
gRefCnt++;
|
||||||
|
|
||||||
if (gRefCnt == 1) {
|
if (gRefCnt == 1) {
|
||||||
#if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||||
Preferences::AddBoolVarCache(&gDOMWindowDumpEnabled,
|
Preferences::AddBoolVarCache(&gDOMWindowDumpEnabled,
|
||||||
"browser.dom.window.dump.enabled");
|
"browser.dom.window.dump.enabled");
|
||||||
#endif
|
#endif
|
||||||
|
@ -4464,7 +4464,7 @@ nsGlobalWindow::GetFullScreen(bool* aFullScreen)
|
||||||
bool
|
bool
|
||||||
nsGlobalWindow::DOMWindowDumpEnabled()
|
nsGlobalWindow::DOMWindowDumpEnabled()
|
||||||
{
|
{
|
||||||
#if !(defined(NS_DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||||
// In optimized builds we check a pref that controls if we should
|
// In optimized builds we check a pref that controls if we should
|
||||||
// enable output from dump() or not, in debug builds it's always
|
// enable output from dump() or not, in debug builds it's always
|
||||||
// enabled.
|
// enabled.
|
||||||
|
@ -8631,7 +8631,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
|
||||||
aJSCallerContext, aReturn),
|
aJSCallerContext, aReturn),
|
||||||
NS_ERROR_NOT_INITIALIZED);
|
NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
PRUint32 argc = 0;
|
PRUint32 argc = 0;
|
||||||
if (argv)
|
if (argv)
|
||||||
argv->GetLength(&argc);
|
argv->GetLength(&argc);
|
||||||
|
|
|
@ -1676,7 +1676,7 @@ nsJSContext::JSObjectFromInterface(nsISupports* aTarget, JSObject* aScope, JSObj
|
||||||
nsresult rv = nsContentUtils::WrapNative(mContext, aScope, aTarget, &v);
|
nsresult rv = nsContentUtils::WrapNative(mContext, aScope, aTarget, &v);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsCOMPtr<nsISupports> targetSupp = do_QueryInterface(aTarget);
|
nsCOMPtr<nsISupports> targetSupp = do_QueryInterface(aTarget);
|
||||||
nsCOMPtr<nsISupports> native =
|
nsCOMPtr<nsISupports> native =
|
||||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(mContext,
|
nsContentUtils::XPConnect()->GetNativeOfWrapper(mContext,
|
||||||
|
@ -2216,7 +2216,7 @@ nsJSContext::ConvertSupportsTojsvals(nsISupports *aArgs,
|
||||||
if (rv == NS_ERROR_NO_INTERFACE) {
|
if (rv == NS_ERROR_NO_INTERFACE) {
|
||||||
// something else - probably an event object or similar -
|
// something else - probably an event object or similar -
|
||||||
// just wrap it.
|
// just wrap it.
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
// but first, check its not another nsISupportsPrimitive, as
|
// but first, check its not another nsISupportsPrimitive, as
|
||||||
// these are now deprecated for use with script contexts.
|
// these are now deprecated for use with script contexts.
|
||||||
nsCOMPtr<nsISupportsPrimitive> prim(do_QueryInterface(arg));
|
nsCOMPtr<nsISupportsPrimitive> prim(do_QueryInterface(arg));
|
||||||
|
|
|
@ -236,9 +236,9 @@ CollectWindowReports(nsGlobalWindow *aWindow,
|
||||||
REPORT("/layout/frames/" # classname, frameSize, \
|
REPORT("/layout/frames/" # classname, frameSize, \
|
||||||
"Memory used by frames of " \
|
"Memory used by frames of " \
|
||||||
"type " #classname " within a window."); \
|
"type " #classname " within a window."); \
|
||||||
aWindowTotalSizes->mArenaStats.FRAME_ID_STAT_FIELD(classname) \
|
|
||||||
+= frameSize; \
|
|
||||||
} \
|
} \
|
||||||
|
aWindowTotalSizes->mArenaStats.FRAME_ID_STAT_FIELD(classname) \
|
||||||
|
+= frameSize; \
|
||||||
}
|
}
|
||||||
#include "nsFrameIdList.h"
|
#include "nsFrameIdList.h"
|
||||||
#undef FRAME_ID
|
#undef FRAME_ID
|
||||||
|
|
|
@ -2370,11 +2370,14 @@ class Tokenizer(object):
|
||||||
lexpos=self.lexer.lexpos,
|
lexpos=self.lexer.lexpos,
|
||||||
filename = self.filename))
|
filename = self.filename))
|
||||||
|
|
||||||
def __init__(self, outputdir):
|
def __init__(self, outputdir, lexer=None):
|
||||||
self.lexer = lex.lex(object=self,
|
if lexer:
|
||||||
outputdir=outputdir,
|
self.lexer = lexer
|
||||||
lextab='webidllex',
|
else:
|
||||||
reflags=re.DOTALL)
|
self.lexer = lex.lex(object=self,
|
||||||
|
outputdir=outputdir,
|
||||||
|
lextab='webidllex',
|
||||||
|
reflags=re.DOTALL)
|
||||||
|
|
||||||
class Parser(Tokenizer):
|
class Parser(Tokenizer):
|
||||||
def getLocation(self, p, i):
|
def getLocation(self, p, i):
|
||||||
|
@ -3459,11 +3462,13 @@ class Parser(Tokenizer):
|
||||||
else:
|
else:
|
||||||
raise WebIDLError("invalid syntax", Location(self.lexer, p.lineno, p.lexpos, self._filename))
|
raise WebIDLError("invalid syntax", Location(self.lexer, p.lineno, p.lexpos, self._filename))
|
||||||
|
|
||||||
def __init__(self, outputdir=''):
|
def __init__(self, outputdir='', lexer=None):
|
||||||
Tokenizer.__init__(self, outputdir)
|
Tokenizer.__init__(self, outputdir, lexer)
|
||||||
self.parser = yacc.yacc(module=self,
|
self.parser = yacc.yacc(module=self,
|
||||||
outputdir=outputdir,
|
outputdir=outputdir,
|
||||||
tabmodule='webidlyacc')
|
tabmodule='webidlyacc',
|
||||||
|
errorlog=yacc.NullLogger(),
|
||||||
|
picklefile='WebIDLGrammar.pkl')
|
||||||
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
|
self._globalScope = IDLScope(BuiltinLocation("<Global Scope>"), None, None)
|
||||||
self._installBuiltins(self._globalScope)
|
self._installBuiltins(self._globalScope)
|
||||||
self._productions = []
|
self._productions = []
|
||||||
|
@ -3535,7 +3540,7 @@ class Parser(Tokenizer):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
return Parser()
|
return Parser(lexer=self.lexer)
|
||||||
|
|
||||||
# Builtin IDL defined by WebIDL
|
# Builtin IDL defined by WebIDL
|
||||||
_builtins = """
|
_builtins = """
|
||||||
|
|
|
@ -58,6 +58,7 @@ $(CPPSRCS): ../%Binding.cpp: $(bindinggen_dependencies) \
|
||||||
|
|
||||||
_TEST_FILES = \
|
_TEST_FILES = \
|
||||||
test_enums.html \
|
test_enums.html \
|
||||||
|
test_integers.html \
|
||||||
test_interfaceToString.html \
|
test_interfaceToString.html \
|
||||||
test_lookupGetter.html \
|
test_lookupGetter.html \
|
||||||
test_InstanceOf.html \
|
test_InstanceOf.html \
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
<canvas id="c" width="1" height="1"></canvas>
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
function testInt64NonFinite(arg) {
|
||||||
|
// We can use a WebGLRenderingContext to test conversion to 64-bit signed
|
||||||
|
// ints edge cases.
|
||||||
|
try {
|
||||||
|
var gl = $("c").getContext("experimental-webgl");
|
||||||
|
} catch (ex) {
|
||||||
|
// No WebGL support on MacOS 10.5. Just skip this test
|
||||||
|
todo(false, "WebGL not supported");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is(gl.getError(), 0, "Should not start in an error state");
|
||||||
|
|
||||||
|
var b = gl.createBuffer();
|
||||||
|
gl.bindBuffer(gl.ARRAY_BUFFER, b);
|
||||||
|
|
||||||
|
var a = new Float32Array(1);
|
||||||
|
gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
|
||||||
|
|
||||||
|
gl.bufferSubData(gl.ARRAY_BUFFER, arg, a);
|
||||||
|
|
||||||
|
is(gl.getError(), 0, "Should have treated non-finite double as 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
testInt64NonFinite(NaN);
|
||||||
|
testInt64NonFinite(Infinity);
|
||||||
|
testInt64NonFinite(-Infinity);
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -94,6 +94,12 @@ BrowserElementChild.prototype = {
|
||||||
windowUtils.setIsApp(false);
|
windowUtils.setIsApp(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A cache of the menuitem dom objects keyed by the id we generate
|
||||||
|
// and pass to the embedder
|
||||||
|
this._ctxHandlers = {};
|
||||||
|
// Counter of contextmenu events fired
|
||||||
|
this._ctxCounter = 0;
|
||||||
|
|
||||||
addEventListener('DOMTitleChanged',
|
addEventListener('DOMTitleChanged',
|
||||||
this._titleChangedHandler.bind(this),
|
this._titleChangedHandler.bind(this),
|
||||||
/* useCapture = */ true,
|
/* useCapture = */ true,
|
||||||
|
@ -116,6 +122,7 @@ BrowserElementChild.prototype = {
|
||||||
addMsgListener("go-back", this._recvGoBack);
|
addMsgListener("go-back", this._recvGoBack);
|
||||||
addMsgListener("go-forward", this._recvGoForward);
|
addMsgListener("go-forward", this._recvGoForward);
|
||||||
addMsgListener("unblock-modal-prompt", this._recvStopWaiting);
|
addMsgListener("unblock-modal-prompt", this._recvStopWaiting);
|
||||||
|
addMsgListener("fire-ctx-callback", this._recvFireCtxCallback);
|
||||||
|
|
||||||
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||||
.getService(Ci.nsIEventListenerService);
|
.getService(Ci.nsIEventListenerService);
|
||||||
|
@ -134,6 +141,9 @@ BrowserElementChild.prototype = {
|
||||||
els.addSystemEventListener(global, 'DOMWindowClose',
|
els.addSystemEventListener(global, 'DOMWindowClose',
|
||||||
this._closeHandler.bind(this),
|
this._closeHandler.bind(this),
|
||||||
/* useCapture = */ false);
|
/* useCapture = */ false);
|
||||||
|
els.addSystemEventListener(global, 'contextmenu',
|
||||||
|
this._contextmenuHandler.bind(this),
|
||||||
|
/* useCapture = */ false);
|
||||||
},
|
},
|
||||||
|
|
||||||
_tryGetInnerWindowID: function(win) {
|
_tryGetInnerWindowID: function(win) {
|
||||||
|
@ -312,6 +322,61 @@ BrowserElementChild.prototype = {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_contextmenuHandler: function(e) {
|
||||||
|
debug("Got contextmenu");
|
||||||
|
|
||||||
|
if (e.defaultPrevented) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
this._ctxCounter++;
|
||||||
|
this._ctxHandlers = {};
|
||||||
|
|
||||||
|
var elem = e.target;
|
||||||
|
var menuData = {systemTargets: [], contextmenu: null};
|
||||||
|
var ctxMenuId = null;
|
||||||
|
|
||||||
|
while (elem && elem.hasAttribute) {
|
||||||
|
var ctxData = this._getSystemCtxMenuData(elem);
|
||||||
|
if (ctxData) {
|
||||||
|
menuData.systemTargets.push({
|
||||||
|
nodeName: elem.nodeName,
|
||||||
|
data: ctxData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ctxMenuId && elem.hasAttribute('contextmenu')) {
|
||||||
|
ctxMenuId = elem.getAttribute('contextmenu');
|
||||||
|
}
|
||||||
|
elem = elem.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctxMenuId) {
|
||||||
|
var menu = e.target.ownerDocument.getElementById(ctxMenuId);
|
||||||
|
if (menu) {
|
||||||
|
menuData.contextmenu = this._buildMenuObj(menu, '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sendAsyncMsg('contextmenu', menuData);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getSystemCtxMenuData: function(elem) {
|
||||||
|
if ((elem instanceof Ci.nsIDOMHTMLAnchorElement && elem.href) ||
|
||||||
|
(elem instanceof Ci.nsIDOMHTMLAreaElement && elem.href)) {
|
||||||
|
return elem.href;
|
||||||
|
}
|
||||||
|
if (elem instanceof Ci.nsIImageLoadingContent && elem.currentURI) {
|
||||||
|
return elem.currentURI.spec;
|
||||||
|
}
|
||||||
|
if ((elem instanceof Ci.nsIDOMHTMLMediaElement) ||
|
||||||
|
(elem instanceof Ci.nsIDOMHTMLImageElement)) {
|
||||||
|
return elem.currentSrc || elem.src;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
_recvGetScreenshot: function(data) {
|
_recvGetScreenshot: function(data) {
|
||||||
debug("Received getScreenshot message: (" + data.json.id + ")");
|
debug("Received getScreenshot message: (" + data.json.id + ")");
|
||||||
var canvas = content.document
|
var canvas = content.document
|
||||||
|
@ -328,6 +393,42 @@ BrowserElementChild.prototype = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_recvFireCtxCallback: function(data) {
|
||||||
|
debug("Received fireCtxCallback message: (" + data.json.menuitem + ")");
|
||||||
|
// We silently ignore if the embedder uses an incorrect id in the callback
|
||||||
|
if (data.json.menuitem in this._ctxHandlers) {
|
||||||
|
this._ctxHandlers[data.json.menuitem].click();
|
||||||
|
this._ctxHandlers = {};
|
||||||
|
} else {
|
||||||
|
debug("Ignored invalid contextmenu invokation");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildMenuObj: function(menu, idPrefix) {
|
||||||
|
function maybeCopyAttribute(src, target, attribute) {
|
||||||
|
if (src.getAttribute(attribute)) {
|
||||||
|
target[attribute] = src.getAttribute(attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var menuObj = {type: 'menu', items: []};
|
||||||
|
maybeCopyAttribute(menu, menuObj, 'label');
|
||||||
|
|
||||||
|
for (var i = 0, child; child = menu.children[i++];) {
|
||||||
|
if (child.nodeName === 'MENU') {
|
||||||
|
menuObj.items.push(this._buildMenuObj(child, idPrefix + i + '_'));
|
||||||
|
} else if (child.nodeName === 'MENUITEM') {
|
||||||
|
var id = this._ctxCounter + '_' + idPrefix + i;
|
||||||
|
var menuitem = {id: id, type: 'menuitem'};
|
||||||
|
maybeCopyAttribute(child, menuitem, 'label');
|
||||||
|
maybeCopyAttribute(child, menuitem, 'icon');
|
||||||
|
this._ctxHandlers[id] = child;
|
||||||
|
menuObj.items.push(menuitem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return menuObj;
|
||||||
|
},
|
||||||
|
|
||||||
_recvSetVisible: function(data) {
|
_recvSetVisible: function(data) {
|
||||||
debug("Received setVisible message: (" + data.json.visible + ")");
|
debug("Received setVisible message: (" + data.json.visible + ")");
|
||||||
if (docShell.isActive !== data.json.visible) {
|
if (docShell.isActive !== data.json.visible) {
|
||||||
|
|
|
@ -0,0 +1,413 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let Cu = Components.utils;
|
||||||
|
let Ci = Components.interfaces;
|
||||||
|
let Cc = Components.classes;
|
||||||
|
let Cr = Components.results;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
|
||||||
|
|
||||||
|
// Event whitelisted for bubbling.
|
||||||
|
let whitelistedEvents = [
|
||||||
|
Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE, // Back button.
|
||||||
|
Ci.nsIDOMKeyEvent.DOM_VK_SLEEP, // Power button.
|
||||||
|
Ci.nsIDOMKeyEvent.DOM_VK_CONTEXT_MENU,
|
||||||
|
Ci.nsIDOMKeyEvent.DOM_VK_F5, // Search button.
|
||||||
|
Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP, // Volume up.
|
||||||
|
Ci.nsIDOMKeyEvent.DOM_VK_PAGE_DOWN // Volume down.
|
||||||
|
];
|
||||||
|
|
||||||
|
function debug(msg) {
|
||||||
|
//dump("BrowserElementChild - " + msg + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendAsyncMsg(msg, data) {
|
||||||
|
sendAsyncMessage('browser-element-api:' + msg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendSyncMsg(msg, data) {
|
||||||
|
return sendSyncMessage('browser-element-api:' + msg, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The BrowserElementChild implements one half of <iframe mozbrowser>.
|
||||||
|
* (The other half is, unsurprisingly, BrowserElementParent.)
|
||||||
|
*
|
||||||
|
* This script is injected into an <iframe mozbrowser> via
|
||||||
|
* nsIMessageManager::LoadFrameScript().
|
||||||
|
*
|
||||||
|
* Our job here is to listen for events within this frame and bubble them up to
|
||||||
|
* the parent process.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var global = this;
|
||||||
|
|
||||||
|
function BrowserElementChild() {
|
||||||
|
// Maps outer window id --> weak ref to window. Used by modal dialog code.
|
||||||
|
this._windowIDDict = {};
|
||||||
|
|
||||||
|
this._init();
|
||||||
|
};
|
||||||
|
|
||||||
|
BrowserElementChild.prototype = {
|
||||||
|
_init: function() {
|
||||||
|
debug("Starting up.");
|
||||||
|
sendAsyncMsg("hello");
|
||||||
|
|
||||||
|
BrowserElementPromptService.mapWindowToBrowserElementChild(content, this);
|
||||||
|
|
||||||
|
docShell.isBrowserFrame = true;
|
||||||
|
docShell.QueryInterface(Ci.nsIWebProgress)
|
||||||
|
.addProgressListener(this._progressListener,
|
||||||
|
Ci.nsIWebProgress.NOTIFY_LOCATION |
|
||||||
|
Ci.nsIWebProgress.NOTIFY_SECURITY |
|
||||||
|
Ci.nsIWebProgress.NOTIFY_STATE_WINDOW);
|
||||||
|
|
||||||
|
// This is necessary to get security web progress notifications.
|
||||||
|
var securityUI = Cc['@mozilla.org/secure_browser_ui;1']
|
||||||
|
.createInstance(Ci.nsISecureBrowserUI);
|
||||||
|
securityUI.init(content);
|
||||||
|
|
||||||
|
// A mozbrowser iframe contained inside a mozapp iframe should return false
|
||||||
|
// for nsWindowUtils::IsPartOfApp (unless the mozbrowser iframe is itself
|
||||||
|
// also mozapp). That is, mozapp is transitive down to its children, but
|
||||||
|
// mozbrowser serves as a barrier.
|
||||||
|
//
|
||||||
|
// This is because mozapp iframes have some privileges which we don't want
|
||||||
|
// to extend to untrusted mozbrowser content.
|
||||||
|
//
|
||||||
|
// Get the app manifest from the parent, if our frame has one.
|
||||||
|
let appManifestURL = sendSyncMsg('get-mozapp-manifest-url')[0];
|
||||||
|
let windowUtils = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
|
||||||
|
if (!!appManifestURL) {
|
||||||
|
windowUtils.setIsApp(true);
|
||||||
|
windowUtils.setApp(appManifestURL);
|
||||||
|
} else {
|
||||||
|
windowUtils.setIsApp(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener('DOMTitleChanged',
|
||||||
|
this._titleChangedHandler.bind(this),
|
||||||
|
/* useCapture = */ true,
|
||||||
|
/* wantsUntrusted = */ false);
|
||||||
|
|
||||||
|
addEventListener('DOMLinkAdded',
|
||||||
|
this._iconChangedHandler.bind(this),
|
||||||
|
/* useCapture = */ true,
|
||||||
|
/* wantsUntrusted = */ false);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
function addMsgListener(msg, handler) {
|
||||||
|
addMessageListener('browser-element-api:' + msg, handler.bind(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
addMsgListener("get-screenshot", this._recvGetScreenshot);
|
||||||
|
addMsgListener("set-visible", this._recvSetVisible);
|
||||||
|
addMsgListener("unblock-modal-prompt", this._recvStopWaiting);
|
||||||
|
|
||||||
|
let els = Cc["@mozilla.org/eventlistenerservice;1"]
|
||||||
|
.getService(Ci.nsIEventListenerService);
|
||||||
|
|
||||||
|
// We are using the system group for those events so if something in the
|
||||||
|
// content called .stopPropagation() this will still be called.
|
||||||
|
els.addSystemEventListener(global, 'keydown',
|
||||||
|
this._keyEventHandler.bind(this),
|
||||||
|
/* useCapture = */ true);
|
||||||
|
els.addSystemEventListener(global, 'keypress',
|
||||||
|
this._keyEventHandler.bind(this),
|
||||||
|
/* useCapture = */ true);
|
||||||
|
els.addSystemEventListener(global, 'keyup',
|
||||||
|
this._keyEventHandler.bind(this),
|
||||||
|
/* useCapture = */ true);
|
||||||
|
els.addSystemEventListener(global, 'DOMWindowClose',
|
||||||
|
this._closeHandler.bind(this),
|
||||||
|
/* useCapture = */ false);
|
||||||
|
},
|
||||||
|
|
||||||
|
_tryGetInnerWindowID: function(win) {
|
||||||
|
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
try {
|
||||||
|
return utils.currentInnerWindowID;
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show a modal prompt. Called by BrowserElementPromptService.
|
||||||
|
*/
|
||||||
|
showModalPrompt: function(win, args) {
|
||||||
|
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
|
||||||
|
args.windowID = { outer: utils.outerWindowID,
|
||||||
|
inner: this._tryGetInnerWindowID(win) };
|
||||||
|
sendAsyncMsg('showmodalprompt', args);
|
||||||
|
|
||||||
|
let returnValue = this._waitForResult(win);
|
||||||
|
|
||||||
|
if (args.promptType == 'prompt' ||
|
||||||
|
args.promptType == 'confirm') {
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spin in a nested event loop until we receive a unblock-modal-prompt message for
|
||||||
|
* this window.
|
||||||
|
*/
|
||||||
|
_waitForResult: function(win) {
|
||||||
|
debug("_waitForResult(" + win + ")");
|
||||||
|
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
|
|
||||||
|
let outerWindowID = utils.outerWindowID;
|
||||||
|
let innerWindowID = this._tryGetInnerWindowID(win);
|
||||||
|
if (innerWindowID === null) {
|
||||||
|
// I have no idea what waiting for a result means when there's no inner
|
||||||
|
// window, so let's just bail.
|
||||||
|
debug("_waitForResult: No inner window. Bailing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._windowIDDict[outerWindowID] = Cu.getWeakReference(win);
|
||||||
|
|
||||||
|
debug("Entering modal state (outerWindowID=" + outerWindowID + ", " +
|
||||||
|
"innerWindowID=" + innerWindowID + ")");
|
||||||
|
|
||||||
|
// In theory, we're supposed to pass |modalStateWin| back to
|
||||||
|
// leaveModalStateWithWindow. But in practice, the window is always null,
|
||||||
|
// because it's the window associated with this script context, which
|
||||||
|
// doesn't have a window. But we'll play along anyway in case this
|
||||||
|
// changes.
|
||||||
|
var modalStateWin = utils.enterModalStateWithWindow();
|
||||||
|
|
||||||
|
// We'll decrement win.modalDepth when we receive a unblock-modal-prompt message
|
||||||
|
// for the window.
|
||||||
|
if (!win.modalDepth) {
|
||||||
|
win.modalDepth = 0;
|
||||||
|
}
|
||||||
|
win.modalDepth++;
|
||||||
|
let origModalDepth = win.modalDepth;
|
||||||
|
|
||||||
|
let thread = Services.tm.currentThread;
|
||||||
|
debug("Nested event loop - begin");
|
||||||
|
while (win.modalDepth == origModalDepth) {
|
||||||
|
// Bail out of the loop if the inner window changed; that means the
|
||||||
|
// window navigated.
|
||||||
|
if (this._tryGetInnerWindowID(win) !== innerWindowID) {
|
||||||
|
debug("_waitForResult: Inner window ID changed " +
|
||||||
|
"while in nested event loop.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread.processNextEvent(/* mayWait = */ true);
|
||||||
|
}
|
||||||
|
debug("Nested event loop - finish");
|
||||||
|
|
||||||
|
// If we exited the loop because the inner window changed, then bail on the
|
||||||
|
// modal prompt.
|
||||||
|
if (innerWindowID !== this._tryGetInnerWindowID(win)) {
|
||||||
|
throw Components.Exception("Modal state aborted by navigation",
|
||||||
|
Cr.NS_ERROR_NOT_AVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
let returnValue = win.modalReturnValue;
|
||||||
|
delete win.modalReturnValue;
|
||||||
|
|
||||||
|
utils.leaveModalStateWithWindow(modalStateWin);
|
||||||
|
|
||||||
|
debug("Leaving modal state (outerID=" + outerWindowID + ", " +
|
||||||
|
"innerID=" + innerWindowID + ")");
|
||||||
|
return returnValue;
|
||||||
|
},
|
||||||
|
|
||||||
|
_recvStopWaiting: function(msg) {
|
||||||
|
let outerID = msg.json.windowID.outer;
|
||||||
|
let innerID = msg.json.windowID.inner;
|
||||||
|
let returnValue = msg.json.returnValue;
|
||||||
|
debug("recvStopWaiting(outer=" + outerID + ", inner=" + innerID +
|
||||||
|
", returnValue=" + returnValue + ")");
|
||||||
|
|
||||||
|
if (!this._windowIDDict[outerID]) {
|
||||||
|
debug("recvStopWaiting: No record of outer window ID " + outerID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let win = this._windowIDDict[outerID].get();
|
||||||
|
delete this._windowIDDict[outerID];
|
||||||
|
|
||||||
|
if (!win) {
|
||||||
|
debug("recvStopWaiting, but window is gone\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (innerID !== this._tryGetInnerWindowID(win)) {
|
||||||
|
debug("recvStopWaiting, but inner ID has changed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("recvStopWaiting " + win);
|
||||||
|
win.modalReturnValue = returnValue;
|
||||||
|
win.modalDepth--;
|
||||||
|
},
|
||||||
|
|
||||||
|
_titleChangedHandler: function(e) {
|
||||||
|
debug("Got titlechanged: (" + e.target.title + ")");
|
||||||
|
var win = e.target.defaultView;
|
||||||
|
|
||||||
|
// Ignore titlechanges which don't come from the top-level
|
||||||
|
// <iframe mozbrowser> window.
|
||||||
|
if (win == content) {
|
||||||
|
sendAsyncMsg('titlechange', e.target.title);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug("Not top level!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_iconChangedHandler: function(e) {
|
||||||
|
debug("Got iconchanged: (" + e.target.href + ")");
|
||||||
|
var hasIcon = e.target.rel.split(' ').some(function(x) {
|
||||||
|
return x.toLowerCase() === 'icon';
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasIcon) {
|
||||||
|
var win = e.target.ownerDocument.defaultView;
|
||||||
|
// Ignore iconchanges which don't come from the top-level
|
||||||
|
// <iframe mozbrowser> window.
|
||||||
|
if (win == content) {
|
||||||
|
sendAsyncMsg('iconchange', e.target.href);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug("Not top level!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_closeHandler: function(e) {
|
||||||
|
let win = e.target;
|
||||||
|
if (win != content || e.defaultPrevented) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Closing window " + win);
|
||||||
|
sendAsyncMsg('close');
|
||||||
|
|
||||||
|
// Inform the window implementation that we handled this close ourselves.
|
||||||
|
e.preventDefault();
|
||||||
|
},
|
||||||
|
|
||||||
|
_recvGetScreenshot: function(data) {
|
||||||
|
debug("Received getScreenshot message: (" + data.json.id + ")");
|
||||||
|
var canvas = content.document
|
||||||
|
.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
canvas.mozOpaque = true;
|
||||||
|
canvas.height = content.innerHeight;
|
||||||
|
canvas.width = content.innerWidth;
|
||||||
|
ctx.drawWindow(content, 0, 0, content.innerWidth,
|
||||||
|
content.innerHeight, "rgb(255,255,255)");
|
||||||
|
sendAsyncMsg('got-screenshot', {
|
||||||
|
id: data.json.id,
|
||||||
|
screenshot: canvas.toDataURL("image/png")
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_recvSetVisible: function(data) {
|
||||||
|
debug("Received setVisible message: (" + data.json.visible + ")");
|
||||||
|
if (docShell.isActive !== data.json.visible) {
|
||||||
|
docShell.isActive = data.json.visible;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_keyEventHandler: function(e) {
|
||||||
|
if (whitelistedEvents.indexOf(e.keyCode) != -1 && !e.defaultPrevented) {
|
||||||
|
sendAsyncMsg('keyevent', {
|
||||||
|
type: e.type,
|
||||||
|
keyCode: e.keyCode,
|
||||||
|
charCode: e.charCode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// The docShell keeps a weak reference to the progress listener, so we need
|
||||||
|
// to keep a strong ref to it ourselves.
|
||||||
|
_progressListener: {
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||||
|
Ci.nsISupportsWeakReference]),
|
||||||
|
_seenLoadStart: false,
|
||||||
|
|
||||||
|
onLocationChange: function(webProgress, request, location, flags) {
|
||||||
|
// We get progress events from subshells here, which is kind of weird.
|
||||||
|
if (webProgress != docShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore locationchange events which occur before the first loadstart.
|
||||||
|
// These are usually about:blank loads we don't care about.
|
||||||
|
if (!this._seenLoadStart) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendAsyncMsg('locationchange', location.spec);
|
||||||
|
},
|
||||||
|
|
||||||
|
onStateChange: function(webProgress, request, stateFlags, status) {
|
||||||
|
if (webProgress != docShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {
|
||||||
|
this._seenLoadStart = true;
|
||||||
|
sendAsyncMsg('loadstart');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||||
|
sendAsyncMsg('loadend');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onSecurityChange: function(webProgress, request, state) {
|
||||||
|
if (webProgress != docShell) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stateDesc;
|
||||||
|
if (state & Ci.nsIWebProgressListener.STATE_IS_SECURE) {
|
||||||
|
stateDesc = 'secure';
|
||||||
|
}
|
||||||
|
else if (state & Ci.nsIWebProgressListener.STATE_IS_BROKEN) {
|
||||||
|
stateDesc = 'broken';
|
||||||
|
}
|
||||||
|
else if (state & Ci.nsIWebProgressListener.STATE_IS_INSECURE) {
|
||||||
|
stateDesc = 'insecure';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debug("Unexpected securitychange state!");
|
||||||
|
stateDesc = '???';
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX Until bug 764496 is fixed, this will always return false.
|
||||||
|
var isEV = !!(state & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL);
|
||||||
|
|
||||||
|
sendAsyncMsg('securitychange', {state: stateDesc, extendedValidation: isEV});
|
||||||
|
},
|
||||||
|
|
||||||
|
onStatusChange: function(webProgress, request, status, message) {},
|
||||||
|
onProgressChange: function(webProgress, request, curSelfProgress,
|
||||||
|
maxSelfProgress, curTotalProgress, maxTotalProgress) {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var api = new BrowserElementChild();
|
|
@ -140,6 +140,7 @@ function BrowserElementParent(frameLoader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
addMessageListener("hello", this._recvHello);
|
addMessageListener("hello", this._recvHello);
|
||||||
|
addMessageListener("contextmenu", this._fireCtxMenuEvent);
|
||||||
addMessageListener("locationchange", this._fireEventFromMsg);
|
addMessageListener("locationchange", this._fireEventFromMsg);
|
||||||
addMessageListener("loadstart", this._fireEventFromMsg);
|
addMessageListener("loadstart", this._fireEventFromMsg);
|
||||||
addMessageListener("loadend", this._fireEventFromMsg);
|
addMessageListener("loadend", this._fireEventFromMsg);
|
||||||
|
@ -187,6 +188,25 @@ BrowserElementParent.prototype = {
|
||||||
debug("recvHello");
|
debug("recvHello");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_fireCtxMenuEvent: function(data) {
|
||||||
|
let evtName = data.name.substring('browser-element-api:'.length);
|
||||||
|
let detail = data.json;
|
||||||
|
|
||||||
|
debug('fireCtxMenuEventFromMsg: ' + evtName + ' ' + detail);
|
||||||
|
let evt = this._createEvent(evtName, detail);
|
||||||
|
|
||||||
|
if (detail.contextmenu) {
|
||||||
|
var self = this;
|
||||||
|
XPCNativeWrapper.unwrap(evt.detail).contextMenuItemSelected = function(id) {
|
||||||
|
self._sendAsyncMsg('fire-ctx-callback', {menuitem: id});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// The embedder may have default actions on context menu events, so
|
||||||
|
// we fire a context menu event even if the child didn't define a
|
||||||
|
// custom context menu
|
||||||
|
this._frameElement.dispatchEvent(evt);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fire either a vanilla or a custom event, depending on the contents of
|
* Fire either a vanilla or a custom event, depending on the contents of
|
||||||
* |data|.
|
* |data|.
|
||||||
|
|
|
@ -0,0 +1,298 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
let Cu = Components.utils;
|
||||||
|
let Ci = Components.interfaces;
|
||||||
|
let Cc = Components.classes;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
|
const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
|
||||||
|
const BROWSER_FRAMES_ENABLED_PREF = "dom.mozBrowserFramesEnabled";
|
||||||
|
|
||||||
|
function debug(msg) {
|
||||||
|
//dump("BrowserElementParent - " + msg + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BrowserElementParent implements one half of <iframe mozbrowser>. (The other
|
||||||
|
* half is, unsurprisingly, BrowserElementChild.)
|
||||||
|
*
|
||||||
|
* BrowserElementParentFactory detects when we create a windows or docshell
|
||||||
|
* contained inside a <iframe mozbrowser> and creates a BrowserElementParent
|
||||||
|
* object for that window.
|
||||||
|
*
|
||||||
|
* BrowserElementParent injects script to listen for certain events in the
|
||||||
|
* child. We then listen to messages from the child script and take
|
||||||
|
* appropriate action here in the parent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function BrowserElementParentFactory() {
|
||||||
|
this._initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserElementParentFactory.prototype = {
|
||||||
|
classID: Components.ID("{ddeafdac-cb39-47c4-9cb8-c9027ee36d26}"),
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||||
|
Ci.nsISupportsWeakReference]),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called on app startup, and also when the browser frames enabled pref is
|
||||||
|
* changed.
|
||||||
|
*/
|
||||||
|
_init: function() {
|
||||||
|
if (this._initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the pref is disabled, do nothing except wait for the pref to change.
|
||||||
|
// (This is important for tests, if nothing else.)
|
||||||
|
if (!this._browserFramesPrefEnabled()) {
|
||||||
|
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||||
|
prefs.addObserver(BROWSER_FRAMES_ENABLED_PREF, this, /* ownsWeak = */ true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("_init");
|
||||||
|
this._initialized = true;
|
||||||
|
|
||||||
|
// Maps frame elements to BrowserElementParent objects. We never look up
|
||||||
|
// anything in this map; the purpose is to keep the BrowserElementParent
|
||||||
|
// alive for as long as its frame element lives.
|
||||||
|
this._bepMap = new WeakMap();
|
||||||
|
|
||||||
|
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||||
|
os.addObserver(this, 'remote-browser-frame-shown', /* ownsWeak = */ true);
|
||||||
|
os.addObserver(this, 'in-process-browser-frame-shown', /* ownsWeak = */ true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_browserFramesPrefEnabled: function() {
|
||||||
|
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||||
|
try {
|
||||||
|
return prefs.getBoolPref(BROWSER_FRAMES_ENABLED_PREF);
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_observeInProcessBrowserFrameShown: function(frameLoader) {
|
||||||
|
debug("In-process browser frame shown " + frameLoader);
|
||||||
|
this._createBrowserElementParent(frameLoader);
|
||||||
|
},
|
||||||
|
|
||||||
|
_observeRemoteBrowserFrameShown: function(frameLoader) {
|
||||||
|
debug("Remote browser frame shown " + frameLoader);
|
||||||
|
this._createBrowserElementParent(frameLoader);
|
||||||
|
},
|
||||||
|
|
||||||
|
_createBrowserElementParent: function(frameLoader) {
|
||||||
|
let frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||||
|
this._bepMap.set(frameElement, new BrowserElementParent(frameLoader));
|
||||||
|
},
|
||||||
|
|
||||||
|
observe: function(subject, topic, data) {
|
||||||
|
switch(topic) {
|
||||||
|
case 'app-startup':
|
||||||
|
this._init();
|
||||||
|
break;
|
||||||
|
case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
|
||||||
|
if (data == BROWSER_FRAMES_ENABLED_PREF) {
|
||||||
|
this._init();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'remote-browser-frame-shown':
|
||||||
|
this._observeRemoteBrowserFrameShown(subject);
|
||||||
|
break;
|
||||||
|
case 'in-process-browser-frame-shown':
|
||||||
|
this._observeInProcessBrowserFrameShown(subject);
|
||||||
|
break;
|
||||||
|
case 'content-document-global-created':
|
||||||
|
this._observeContentGlobalCreated(subject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function BrowserElementParent(frameLoader) {
|
||||||
|
debug("Creating new BrowserElementParent object for " + frameLoader);
|
||||||
|
this._screenshotListeners = {};
|
||||||
|
this._screenshotReqCounter = 0;
|
||||||
|
|
||||||
|
this._frameElement = frameLoader.QueryInterface(Ci.nsIFrameLoader).ownerElement;
|
||||||
|
if (!this._frameElement) {
|
||||||
|
debug("No frame element?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._mm = frameLoader.messageManager;
|
||||||
|
|
||||||
|
// Messages we receive are handed to functions which take a (data) argument,
|
||||||
|
// where |data| is the message manager's data object.
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
function addMessageListener(msg, handler) {
|
||||||
|
self._mm.addMessageListener('browser-element-api:' + msg, handler.bind(self));
|
||||||
|
}
|
||||||
|
|
||||||
|
addMessageListener("hello", this._recvHello);
|
||||||
|
addMessageListener("locationchange", this._fireEventFromMsg);
|
||||||
|
addMessageListener("loadstart", this._fireEventFromMsg);
|
||||||
|
addMessageListener("loadend", this._fireEventFromMsg);
|
||||||
|
addMessageListener("titlechange", this._fireEventFromMsg);
|
||||||
|
addMessageListener("iconchange", this._fireEventFromMsg);
|
||||||
|
addMessageListener("close", this._fireEventFromMsg);
|
||||||
|
addMessageListener("securitychange", this._fireEventFromMsg);
|
||||||
|
addMessageListener("get-mozapp-manifest-url", this._sendMozAppManifestURL);
|
||||||
|
addMessageListener("keyevent", this._fireKeyEvent);
|
||||||
|
addMessageListener("showmodalprompt", this._handleShowModalPrompt);
|
||||||
|
addMessageListener('got-screenshot', this._recvGotScreenshot);
|
||||||
|
|
||||||
|
function defineMethod(name, fn) {
|
||||||
|
XPCNativeWrapper.unwrap(self._frameElement)[name] = fn.bind(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define methods on the frame element.
|
||||||
|
defineMethod('getScreenshot', this._getScreenshot);
|
||||||
|
defineMethod('setVisible', this._setVisible);
|
||||||
|
|
||||||
|
this._mm.loadFrameScript("chrome://global/content/BrowserElementChild.js",
|
||||||
|
/* allowDelayedLoad = */ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserElementParent.prototype = {
|
||||||
|
get _window() {
|
||||||
|
return this._frameElement.ownerDocument.defaultView;
|
||||||
|
},
|
||||||
|
|
||||||
|
_sendAsyncMsg: function(msg, data) {
|
||||||
|
this._frameElement.QueryInterface(Ci.nsIFrameLoaderOwner)
|
||||||
|
.frameLoader
|
||||||
|
.messageManager
|
||||||
|
.sendAsyncMessage('browser-element-api:' + msg, data);
|
||||||
|
},
|
||||||
|
|
||||||
|
_recvHello: function(data) {
|
||||||
|
debug("recvHello");
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fire either a vanilla or a custom event, depending on the contents of
|
||||||
|
* |data|.
|
||||||
|
*/
|
||||||
|
_fireEventFromMsg: function(data) {
|
||||||
|
let name = data.name.substring('browser-element-api:'.length);
|
||||||
|
let detail = data.json;
|
||||||
|
|
||||||
|
debug('fireEventFromMsg: ' + name + ', ' + detail);
|
||||||
|
let evt = this._createEvent(name, detail,
|
||||||
|
/* cancelable = */ false);
|
||||||
|
this._frameElement.dispatchEvent(evt);
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleShowModalPrompt: function(data) {
|
||||||
|
// Fire a showmodalprmopt event on the iframe. When this method is called,
|
||||||
|
// the child is spinning in a nested event loop waiting for an
|
||||||
|
// unblock-modal-prompt message.
|
||||||
|
//
|
||||||
|
// If the embedder calls preventDefault() on the showmodalprompt event,
|
||||||
|
// we'll block the child until event.detail.unblock() is called.
|
||||||
|
//
|
||||||
|
// Otherwise, if preventDefault() is not called, we'll send the
|
||||||
|
// unblock-modal-prompt message to the child as soon as the event is done
|
||||||
|
// dispatching.
|
||||||
|
|
||||||
|
let detail = data.json;
|
||||||
|
debug('handleShowPrompt ' + JSON.stringify(detail));
|
||||||
|
|
||||||
|
// Strip off the windowID property from the object we send along in the
|
||||||
|
// event.
|
||||||
|
let windowID = detail.windowID;
|
||||||
|
delete detail.windowID;
|
||||||
|
debug("Event will have detail: " + JSON.stringify(detail));
|
||||||
|
let evt = this._createEvent('showmodalprompt', detail,
|
||||||
|
/* cancelable = */ true);
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
let unblockMsgSent = false;
|
||||||
|
function sendUnblockMsg() {
|
||||||
|
if (unblockMsgSent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unblockMsgSent = true;
|
||||||
|
|
||||||
|
// We don't need to sanitize evt.detail.returnValue (e.g. converting the
|
||||||
|
// return value of confirm() to a boolean); Gecko does that for us.
|
||||||
|
|
||||||
|
let data = { windowID: windowID,
|
||||||
|
returnValue: evt.detail.returnValue };
|
||||||
|
self._sendAsyncMsg('unblock-modal-prompt', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
XPCNativeWrapper.unwrap(evt.detail).unblock = function() {
|
||||||
|
sendUnblockMsg();
|
||||||
|
};
|
||||||
|
|
||||||
|
this._frameElement.dispatchEvent(evt);
|
||||||
|
|
||||||
|
if (!evt.defaultPrevented) {
|
||||||
|
// Unblock the inner frame immediately. Otherwise we'll unblock upon
|
||||||
|
// evt.detail.unblock().
|
||||||
|
sendUnblockMsg();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_createEvent: function(evtName, detail, cancelable) {
|
||||||
|
// This will have to change if we ever want to send a CustomEvent with null
|
||||||
|
// detail. For now, it's OK.
|
||||||
|
if (detail !== undefined && detail !== null) {
|
||||||
|
return new this._window.CustomEvent('mozbrowser' + evtName,
|
||||||
|
{ bubbles: true,
|
||||||
|
cancelable: cancelable,
|
||||||
|
detail: detail });
|
||||||
|
}
|
||||||
|
|
||||||
|
return new this._window.Event('mozbrowser' + evtName,
|
||||||
|
{ bubbles: true,
|
||||||
|
cancelable: cancelable });
|
||||||
|
},
|
||||||
|
|
||||||
|
_sendMozAppManifestURL: function(data) {
|
||||||
|
return this._frameElement.getAttribute('mozapp');
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
_getScreenshot: function() {
|
||||||
|
let id = 'req_' + this._screenshotReqCounter++;
|
||||||
|
let req = Services.DOMRequest.createRequest(this._window);
|
||||||
|
this._screenshotListeners[id] = req;
|
||||||
|
this._sendAsyncMsg('get-screenshot', {id: id});
|
||||||
|
return req;
|
||||||
|
},
|
||||||
|
|
||||||
|
_recvGotScreenshot: function(data) {
|
||||||
|
var req = this._screenshotListeners[data.json.id];
|
||||||
|
delete this._screenshotListeners[data.json.id];
|
||||||
|
Services.DOMRequest.fireSuccess(req, data.json.screenshot);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setVisible: function(visible) {
|
||||||
|
this._sendAsyncMsg('set-visible', {visible: visible});
|
||||||
|
},
|
||||||
|
|
||||||
|
_fireKeyEvent: function(data) {
|
||||||
|
let evt = this._window.document.createEvent("KeyboardEvent");
|
||||||
|
evt.initKeyEvent(data.json.type, true, true, this._window,
|
||||||
|
false, false, false, false, // modifiers
|
||||||
|
data.json.keyCode,
|
||||||
|
data.json.charCode);
|
||||||
|
|
||||||
|
this._frameElement.dispatchEvent(evt);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var NSGetFactory = XPCOMUtils.generateNSGetFactory([BrowserElementParentFactory]);
|
|
@ -66,6 +66,8 @@ _TEST_FILES = \
|
||||||
test_browserElement_inproc_SecurityChange.html \
|
test_browserElement_inproc_SecurityChange.html \
|
||||||
file_browserElement_SecurityChange.html \
|
file_browserElement_SecurityChange.html \
|
||||||
browserElement_BackForward.js \
|
browserElement_BackForward.js \
|
||||||
|
browserElement_ContextmenuEvents.js \
|
||||||
|
test_browserElement_inproc_ContextmenuEvents.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# OOP tests don't work on Windows (bug 763081).
|
# OOP tests don't work on Windows (bug 763081).
|
||||||
|
@ -91,6 +93,7 @@ _TEST_FILES += \
|
||||||
test_browserElement_oop_OpenWindowRejected.html \
|
test_browserElement_oop_OpenWindowRejected.html \
|
||||||
test_browserElement_oop_SecurityChange.html \
|
test_browserElement_oop_SecurityChange.html \
|
||||||
test_browserElement_oop_BackForward.html \
|
test_browserElement_oop_BackForward.html \
|
||||||
|
test_browserElement_oop_ContextmenuEvents.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
var iframeScript = function() {
|
||||||
|
|
||||||
|
content.fireContextMenu = function(element) {
|
||||||
|
var ev = content.document.createEvent('HTMLEvents');
|
||||||
|
ev.initEvent('contextmenu', true, false);
|
||||||
|
element.dispatchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
XPCNativeWrapper.unwrap(content).ctxCallbackFired = function(data) {
|
||||||
|
sendAsyncMessage('test:callbackfired', {data: data});
|
||||||
|
}
|
||||||
|
|
||||||
|
XPCNativeWrapper.unwrap(content).onerror = function(e) {
|
||||||
|
sendAsyncMessage('test:errorTriggered', {data: e});
|
||||||
|
}
|
||||||
|
|
||||||
|
content.fireContextMenu(content.document.body);
|
||||||
|
content.fireContextMenu(content.document.getElementById('menu1-trigger'));
|
||||||
|
content.fireContextMenu(content.document.getElementById('inner-link'));
|
||||||
|
content.fireContextMenu(content.document.getElementById('menu2-trigger'));
|
||||||
|
}
|
||||||
|
|
||||||
|
var trigger1 = function() {
|
||||||
|
content.fireContextMenu(content.document.getElementById('menu1-trigger'));
|
||||||
|
};
|
||||||
|
|
||||||
|
function runTest() {
|
||||||
|
|
||||||
|
browserElementTestHelpers.setEnabledPref(true);
|
||||||
|
browserElementTestHelpers.addToWhitelist();
|
||||||
|
|
||||||
|
var iframe1 = document.createElement('iframe');
|
||||||
|
iframe1.mozbrowser = true;
|
||||||
|
document.body.appendChild(iframe1);
|
||||||
|
iframe1.src = 'data:text/html,<html>' +
|
||||||
|
'<body>' +
|
||||||
|
'<menu type="context" id="menu1" label="firstmenu">' +
|
||||||
|
'<menuitem label="foo" onclick="window.ctxCallbackFired(\'foo\')"></menuitem>' +
|
||||||
|
'<menuitem label="bar" onclick="throw(\'anerror\')"></menuitem>' +
|
||||||
|
'</menu>' +
|
||||||
|
'<menu type="context" id="menu2" label="secondmenu">' +
|
||||||
|
'<menuitem label="outer" onclick="window.ctxCallbackFired(\'err\')"></menuitem>' +
|
||||||
|
'<menu>' +
|
||||||
|
'<menuitem label="inner 1"></menuitem>' +
|
||||||
|
'<menuitem label="inner 2" onclick="window.ctxCallbackFired(\'inner2\')"></menuitem>' +
|
||||||
|
'</menu>' +
|
||||||
|
'</menu>' +
|
||||||
|
'<div id="menu1-trigger" contextmenu="menu1"><a id="inner-link" href="foo.html">Menu 1</a></div>' +
|
||||||
|
'<a href="bar.html" contextmenu="menu2"><img id="menu2-trigger" src="example.png" /></a>' +
|
||||||
|
'</body></html>';
|
||||||
|
|
||||||
|
var mm;
|
||||||
|
var numIframeLoaded = 0;
|
||||||
|
var ctxMenuEvents = 0;
|
||||||
|
var ctxCallbackEvents = 0;
|
||||||
|
|
||||||
|
var cachedCtxDetail = null;
|
||||||
|
|
||||||
|
// We fire off various contextmenu events to check the data that gets
|
||||||
|
// passed to the handler
|
||||||
|
function iframeContextmenuHandler(e) {
|
||||||
|
var detail = e.detail;
|
||||||
|
ctxMenuEvents++;
|
||||||
|
if (ctxMenuEvents === 1) {
|
||||||
|
ok(detail.contextmenu === null, 'body context clicks have no context menu');
|
||||||
|
} else if (ctxMenuEvents === 2) {
|
||||||
|
cachedCtxDetail = detail;
|
||||||
|
ok(detail.contextmenu.items.length === 2, 'trigger custom contextmenu');
|
||||||
|
} else if (ctxMenuEvents === 3) {
|
||||||
|
ok(detail.systemTargets.length === 1, 'Includes anchor data');
|
||||||
|
ok(detail.contextmenu.items.length === 2, 'Inner clicks trigger correct menu');
|
||||||
|
} else if (ctxMenuEvents === 4) {
|
||||||
|
var innerMenu = detail.contextmenu.items.filter(function(x) {
|
||||||
|
return x.type === 'menu';
|
||||||
|
});
|
||||||
|
ok(detail.systemTargets.length === 2, 'Includes anchor and img data');
|
||||||
|
ok(innerMenu.length > 0, 'Menu contains a nested menu');
|
||||||
|
ok(true, 'Got correct number of contextmenu events');
|
||||||
|
// Finished testing the data passed to the contextmenu handler,
|
||||||
|
// now we start selecting contextmenu items
|
||||||
|
|
||||||
|
// This is previously triggered contextmenu data, since we have
|
||||||
|
// fired subsequent contextmenus this should not be mistaken
|
||||||
|
// for a current menuitem
|
||||||
|
var prevId = cachedCtxDetail.contextmenu.items[0].id;
|
||||||
|
cachedCtxDetail.contextMenuItemSelected(prevId);
|
||||||
|
// This triggers a current menuitem
|
||||||
|
detail.contextMenuItemSelected(innerMenu[0].items[1].id);
|
||||||
|
// Once an item it selected, subsequent selections are ignored
|
||||||
|
detail.contextMenuItemSelected(innerMenu[0].items[0].id);
|
||||||
|
} else if (ctxMenuEvents === 5) {
|
||||||
|
ok(detail.contextmenu.label === 'firstmenu', 'Correct menu enabled');
|
||||||
|
detail.contextMenuItemSelected(detail.contextmenu.items[0].id);
|
||||||
|
} else if (ctxMenuEvents === 6) {
|
||||||
|
detail.contextMenuItemSelected(detail.contextmenu.items[1].id);
|
||||||
|
} else if (ctxMenuEvents > 6) {
|
||||||
|
ok(false, 'Too many events');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ctxCallbackRecieved(msg) {
|
||||||
|
ctxCallbackEvents++;
|
||||||
|
if (ctxCallbackEvents === 1) {
|
||||||
|
ok(msg.json.data === 'inner2', 'Callback function got fired correctly');
|
||||||
|
mm.loadFrameScript('data:,(' + trigger1.toString() + ')();', false);
|
||||||
|
} else if (ctxCallbackEvents === 2) {
|
||||||
|
ok(msg.json.data === 'foo', 'Callback function got fired correctly');
|
||||||
|
mm.loadFrameScript('data:,(' + trigger1.toString() + ')();', false);
|
||||||
|
} else if (ctxCallbackEvents > 2) {
|
||||||
|
ok(false, 'Too many callback events');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorTriggered(msg) {
|
||||||
|
ok(true, 'An error in the callback triggers window.onerror');
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function iframeLoadedHandler() {
|
||||||
|
numIframeLoaded++;
|
||||||
|
if (numIframeLoaded === 2) {
|
||||||
|
mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
|
||||||
|
mm.addMessageListener('test:callbackfired', ctxCallbackRecieved);
|
||||||
|
mm.addMessageListener('test:errorTriggered', errorTriggered);
|
||||||
|
mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iframe1.addEventListener('mozbrowsercontextmenu', iframeContextmenuHandler);
|
||||||
|
iframe1.addEventListener('mozbrowserloadend', iframeLoadedHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener('load', function() { SimpleTest.executeSoon(runTest); });
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test for Contextmenu Events</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="application/javascript;version=1.7" src="browserElement_ContextmenuEvents.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test for Contextmenu Events</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script type="application/javascript;version=1.7" src="browserElement_ContextmenuEvents.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -291,21 +291,5 @@
|
||||||
"Command outdent, value \"\": input event, uncanceled":true,
|
"Command outdent, value \"\": input event, uncanceled":true,
|
||||||
"Command outdent, value \"quasit\": beforeinput event, canceled":true,
|
"Command outdent, value \"quasit\": beforeinput event, canceled":true,
|
||||||
"Command outdent, value \"quasit\": beforeinput event, uncanceled":true,
|
"Command outdent, value \"quasit\": beforeinput event, uncanceled":true,
|
||||||
"Command outdent, value \"quasit\": input event, uncanceled":true,
|
"Command outdent, value \"quasit\": input event, uncanceled":true
|
||||||
"Command redo, value \"\": beforeinput event, canceled":true,
|
|
||||||
"Command redo, value \"\": input event, canceled":true,
|
|
||||||
"Command redo, value \"\": beforeinput event, uncanceled":true,
|
|
||||||
"Command redo, value \"\": input event, uncanceled":true,
|
|
||||||
"Command redo, value \"quasit\": beforeinput event, canceled":true,
|
|
||||||
"Command redo, value \"quasit\": input event, canceled":true,
|
|
||||||
"Command redo, value \"quasit\": beforeinput event, uncanceled":true,
|
|
||||||
"Command redo, value \"quasit\": input event, uncanceled":true,
|
|
||||||
"Command undo, value \"\": beforeinput event, canceled":true,
|
|
||||||
"Command undo, value \"\": input event, canceled":true,
|
|
||||||
"Command undo, value \"\": beforeinput event, uncanceled":true,
|
|
||||||
"Command undo, value \"\": input event, uncanceled":true,
|
|
||||||
"Command undo, value \"quasit\": beforeinput event, canceled":true,
|
|
||||||
"Command undo, value \"quasit\": input event, canceled":true,
|
|
||||||
"Command undo, value \"quasit\": beforeinput event, uncanceled":true,
|
|
||||||
"Command undo, value \"quasit\": input event, uncanceled":true
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,21 +109,14 @@
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>\" queryCommandIndeterm(\"bold\") before":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>\" queryCommandIndeterm(\"bold\") before":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>\" queryCommandIndeterm(\"bold\") before":true,
|
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<p>[foo</p><p> <span>bar</span> </p><p>baz]</p>\" queryCommandIndeterm(\"bold\") before":true,
|
||||||
"[[\"bold\",\"\"]] \"<span>foo[</span><span>]bar</span>\" queryCommandState(\"bold\") after":true,
|
"[[\"bold\",\"\"]] \"<span>foo[</span><span>]bar</span>\" queryCommandState(\"bold\") after":true,
|
||||||
"[[\"bold\",\"\"]] \"foo<span contenteditable=false>[bar]</span>baz\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"fo[o<span contenteditable=false>bar</span>b]az\" compare innerHTML":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"fo[o<span contenteditable=false>bar</span>b]az\" compare innerHTML":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"fo[o<span contenteditable=false>bar</span>b]az\" compare innerHTML":true,
|
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"fo[o<span contenteditable=false>bar</span>b]az\" compare innerHTML":true,
|
||||||
"[[\"bold\",\"\"]] \"foo<span contenteditable=false>ba[r</span>b]az\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"bold\",\"\"]] \"fo[o<span contenteditable=false>b]ar</span>baz\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" compare innerHTML":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" compare innerHTML":true,
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" queryCommandState(\"bold\") after":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" queryCommandState(\"bold\") after":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" compare innerHTML":true,
|
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" compare innerHTML":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" queryCommandState(\"bold\") after":true,
|
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>[bar]</span>baz</span>\" queryCommandState(\"bold\") after":true,
|
||||||
"[[\"bold\",\"\"]] \"<span contenteditable=false>fo[o<span contenteditable=true>bar</span>b]az</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"bold\",\"\"]] \"<span contenteditable=false>foo<span contenteditable=true>ba[r</span>b]az</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"bold\",\"\"]] \"<span contenteditable=false>fo[o<span contenteditable=true>b]ar</span>baz</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"bold\",\"\"]] \"<span contenteditable=false>fo[<b>o<span contenteditable=true>bar</span>b</b>]az</span>\": execCommand(\"bold\", false, \"\") return value":true,
|
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>\" queryCommandIndeterm(\"bold\") before":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>\" queryCommandIndeterm(\"bold\") before":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>\" queryCommandIndeterm(\"bold\") before":true,
|
"[[\"stylewithcss\",\"false\"],[\"bold\",\"\"]] \"<table><tbody data-start=0 data-end=1><tr><td>foo<td>bar<td>baz</table>\" queryCommandIndeterm(\"bold\") before":true,
|
||||||
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>\" queryCommandIndeterm(\"bold\") before":true,
|
"[[\"stylewithcss\",\"true\"],[\"bold\",\"\"]] \"<table data-start=0 data-end=1><tbody><tr><td>foo<td>bar<td>baz</table>\" queryCommandIndeterm(\"bold\") before":true,
|
||||||
|
@ -1339,10 +1332,8 @@
|
||||||
"[[\"stylewithcss\",\"true\"],[\"fontname\",\"sans-serif\"]] \"foo<span style=\\\"font-family: monospace\\\">b[a]r</span>baz\" compare innerHTML":true,
|
"[[\"stylewithcss\",\"true\"],[\"fontname\",\"sans-serif\"]] \"foo<span style=\\\"font-family: monospace\\\">b[a]r</span>baz\" compare innerHTML":true,
|
||||||
"[[\"stylewithcss\",\"true\"],[\"fontname\",\"sans-serif\"]] \"foo<span style=\\\"font-family: monospace\\\">b[a]r</span>baz\" queryCommandValue(\"fontname\") before":true,
|
"[[\"stylewithcss\",\"true\"],[\"fontname\",\"sans-serif\"]] \"foo<span style=\\\"font-family: monospace\\\">b[a]r</span>baz\" queryCommandValue(\"fontname\") before":true,
|
||||||
"[[\"stylewithcss\",\"false\"],[\"fontname\",\"sans-serif\"]] \"foo<span style=\\\"font-family: monospace\\\">b[a]r</span>baz\" queryCommandValue(\"fontname\") before":true,
|
"[[\"stylewithcss\",\"false\"],[\"fontname\",\"sans-serif\"]] \"foo<span style=\\\"font-family: monospace\\\">b[a]r</span>baz\" queryCommandValue(\"fontname\") before":true,
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"foo<tt contenteditable=false>ba[r</tt>b]az\": execCommand(\"fontname\", false, \"sans-serif\") return value":true,
|
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"foo<tt contenteditable=false>ba[r</tt>b]az\" queryCommandValue(\"fontname\") before":true,
|
"[[\"fontname\",\"sans-serif\"]] \"foo<tt contenteditable=false>ba[r</tt>b]az\" queryCommandValue(\"fontname\") before":true,
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"foo<tt contenteditable=false>ba[r</tt>b]az\" queryCommandValue(\"fontname\") after":true,
|
"[[\"fontname\",\"sans-serif\"]] \"foo<tt contenteditable=false>ba[r</tt>b]az\" queryCommandValue(\"fontname\") after":true,
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"fo[o<tt contenteditable=false>b]ar</tt>baz\": execCommand(\"fontname\", false, \"sans-serif\") return value":true,
|
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"fo[o<tt contenteditable=false>b]ar</tt>baz\" queryCommandValue(\"fontname\") before":true,
|
"[[\"fontname\",\"sans-serif\"]] \"fo[o<tt contenteditable=false>b]ar</tt>baz\" queryCommandValue(\"fontname\") before":true,
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"fo[o<tt contenteditable=false>b]ar</tt>baz\" queryCommandValue(\"fontname\") after":true,
|
"[[\"fontname\",\"sans-serif\"]] \"fo[o<tt contenteditable=false>b]ar</tt>baz\" queryCommandValue(\"fontname\") after":true,
|
||||||
"[[\"fontname\",\"sans-serif\"]] \"foo<tt>{}<br></tt>bar\" queryCommandValue(\"fontname\") before":true,
|
"[[\"fontname\",\"sans-serif\"]] \"foo<tt>{}<br></tt>bar\" queryCommandValue(\"fontname\") before":true,
|
||||||
|
|
|
@ -1714,7 +1714,7 @@ IDBObjectStore::IndexInternal(const nsAString& aName,
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
if (!mTransaction->IsOpen()) {
|
if (mTransaction->IsFinished()) {
|
||||||
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -499,10 +499,7 @@ IDBTransaction::AbortWithCode(nsresult aAbortCode)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
// We can't use IsOpen here since we need it to be possible to call Abort()
|
if (IsFinished()) {
|
||||||
// even from outside of transaction callbacks.
|
|
||||||
if (mReadyState != IDBTransaction::INITIAL &&
|
|
||||||
mReadyState != IDBTransaction::LOADING) {
|
|
||||||
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -683,7 +680,7 @@ IDBTransaction::ObjectStoreInternal(const nsAString& aName,
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
|
||||||
if (!IsOpen()) {
|
if (IsFinished()) {
|
||||||
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,6 +816,10 @@ CommitHelper::Run()
|
||||||
}
|
}
|
||||||
NS_ENSURE_TRUE(event, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
NS_ENSURE_TRUE(event, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||||
|
|
||||||
|
if (mListener) {
|
||||||
|
mListener->NotifyTransactionPreComplete(mTransaction);
|
||||||
|
}
|
||||||
|
|
||||||
bool dummy;
|
bool dummy;
|
||||||
if (NS_FAILED(mTransaction->DispatchEvent(event, &dummy))) {
|
if (NS_FAILED(mTransaction->DispatchEvent(event, &dummy))) {
|
||||||
NS_WARNING("Dispatch failed!");
|
NS_WARNING("Dispatch failed!");
|
||||||
|
@ -828,9 +829,8 @@ CommitHelper::Run()
|
||||||
mTransaction->mFiredCompleteOrAbort = true;
|
mTransaction->mFiredCompleteOrAbort = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Tell the listener (if we have one) that we're done
|
|
||||||
if (mListener) {
|
if (mListener) {
|
||||||
mListener->NotifyTransactionComplete(mTransaction);
|
mListener->NotifyTransactionPostComplete(mTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
mTransaction = nsnull;
|
mTransaction = nsnull;
|
||||||
|
|
|
@ -45,7 +45,10 @@ public:
|
||||||
NS_IMETHOD_(nsrefcnt) AddRef() = 0;
|
NS_IMETHOD_(nsrefcnt) AddRef() = 0;
|
||||||
NS_IMETHOD_(nsrefcnt) Release() = 0;
|
NS_IMETHOD_(nsrefcnt) Release() = 0;
|
||||||
|
|
||||||
virtual nsresult NotifyTransactionComplete(IDBTransaction* aTransaction) = 0;
|
// Called just before dispatching the final events on the transaction.
|
||||||
|
virtual nsresult NotifyTransactionPreComplete(IDBTransaction* aTransaction) = 0;
|
||||||
|
// Called just after dispatching the final events on the transaction.
|
||||||
|
virtual nsresult NotifyTransactionPostComplete(IDBTransaction* aTransaction) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IDBTransaction : public IDBWrapperCache,
|
class IDBTransaction : public IDBWrapperCache,
|
||||||
|
@ -122,6 +125,11 @@ public:
|
||||||
|
|
||||||
bool IsOpen() const;
|
bool IsOpen() const;
|
||||||
|
|
||||||
|
bool IsFinished() const
|
||||||
|
{
|
||||||
|
return mReadyState > LOADING;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsWriteAllowed() const
|
bool IsWriteAllowed() const
|
||||||
{
|
{
|
||||||
return mMode == READ_WRITE || mMode == VERSION_CHANGE;
|
return mMode == READ_WRITE || mMode == VERSION_CHANGE;
|
||||||
|
|
|
@ -1352,8 +1352,10 @@ protected:
|
||||||
// Need an upgradeneeded event here.
|
// Need an upgradeneeded event here.
|
||||||
virtual already_AddRefed<nsDOMEvent> CreateSuccessEvent() MOZ_OVERRIDE;
|
virtual already_AddRefed<nsDOMEvent> CreateSuccessEvent() MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual nsresult NotifyTransactionComplete(IDBTransaction* aTransaction)
|
virtual nsresult NotifyTransactionPreComplete(IDBTransaction* aTransaction)
|
||||||
MOZ_OVERRIDE;
|
MOZ_OVERRIDE;
|
||||||
|
virtual nsresult NotifyTransactionPostComplete(IDBTransaction* aTransaction)
|
||||||
|
MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual ChildProcessSendResult
|
virtual ChildProcessSendResult
|
||||||
MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE
|
MaybeSendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE
|
||||||
|
@ -1956,12 +1958,6 @@ OpenDatabaseHelper::Run()
|
||||||
|
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
case eSetVersionCompleted: {
|
case eSetVersionCompleted: {
|
||||||
// Allow transaction creation/other version change transactions to proceed
|
|
||||||
// before we fire events. Other version changes will be postd to the end
|
|
||||||
// of the event loop, and will be behind whatever the page does in
|
|
||||||
// its error/success event handlers.
|
|
||||||
mDatabase->ExitSetVersionTransaction();
|
|
||||||
|
|
||||||
mState = eFiringEvents;
|
mState = eFiringEvents;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2134,6 +2130,9 @@ OpenDatabaseHelper::NotifySetVersionFinished()
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread");
|
||||||
NS_ASSERTION(mState = eSetVersionPending, "How did we get here?");
|
NS_ASSERTION(mState = eSetVersionPending, "How did we get here?");
|
||||||
|
|
||||||
|
// Allow transaction creation to proceed.
|
||||||
|
mDatabase->ExitSetVersionTransaction();
|
||||||
|
|
||||||
mState = eSetVersionCompleted;
|
mState = eSetVersionCompleted;
|
||||||
|
|
||||||
// Dispatch ourself back to the main thread
|
// Dispatch ourself back to the main thread
|
||||||
|
@ -2292,7 +2291,17 @@ SetVersionHelper::CreateSuccessEvent()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
SetVersionHelper::NotifyTransactionComplete(IDBTransaction* aTransaction)
|
SetVersionHelper::NotifyTransactionPreComplete(IDBTransaction* aTransaction)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
|
NS_ASSERTION(aTransaction, "This is unexpected.");
|
||||||
|
NS_ASSERTION(mOpenRequest, "Why don't we have a request?");
|
||||||
|
|
||||||
|
return mOpenHelper->NotifySetVersionFinished();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
SetVersionHelper::NotifyTransactionPostComplete(IDBTransaction* aTransaction)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||||
NS_ASSERTION(aTransaction, "This is unexpected.");
|
NS_ASSERTION(aTransaction, "This is unexpected.");
|
||||||
|
@ -2312,7 +2321,6 @@ SetVersionHelper::NotifyTransactionComplete(IDBTransaction* aTransaction)
|
||||||
mOpenRequest->SetTransaction(nsnull);
|
mOpenRequest->SetTransaction(nsnull);
|
||||||
mOpenRequest = nsnull;
|
mOpenRequest = nsnull;
|
||||||
|
|
||||||
rv = mOpenHelper->NotifySetVersionFinished();
|
|
||||||
mOpenHelper = nsnull;
|
mOpenHelper = nsnull;
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -337,7 +337,6 @@ IndexedDBDatabaseChild::RecvSuccess(
|
||||||
|
|
||||||
if (openHelper) {
|
if (openHelper) {
|
||||||
request->Reset();
|
request->Reset();
|
||||||
database->ExitSetVersionTransaction();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
openHelper = new IPCOpenDatabaseHelper(mDatabase, request);
|
openHelper = new IPCOpenDatabaseHelper(mDatabase, request);
|
||||||
|
@ -370,7 +369,6 @@ IndexedDBDatabaseChild::RecvError(const nsresult& aRv)
|
||||||
|
|
||||||
if (openHelper) {
|
if (openHelper) {
|
||||||
request->Reset();
|
request->Reset();
|
||||||
database->ExitSetVersionTransaction();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
openHelper = new IPCOpenDatabaseHelper(NULL, request);
|
openHelper = new IPCOpenDatabaseHelper(NULL, request);
|
||||||
|
@ -540,12 +538,9 @@ IndexedDBTransactionChild::FireCompleteEvent(nsresult aRv)
|
||||||
nsRefPtr<IDBTransaction> transaction;
|
nsRefPtr<IDBTransaction> transaction;
|
||||||
mStrongTransaction.swap(transaction);
|
mStrongTransaction.swap(transaction);
|
||||||
|
|
||||||
// This is where we should allow the database to start issuing new
|
if (transaction->GetMode() == IDBTransaction::VERSION_CHANGE) {
|
||||||
// transactions once we fix the main thread. E.g.:
|
transaction->Database()->ExitSetVersionTransaction();
|
||||||
//
|
}
|
||||||
// if (transaction->GetMode() == IDBTransaction::VERSION_CHANGE) {
|
|
||||||
// transaction->Database()->ExitSetVersionTransaction();
|
|
||||||
// }
|
|
||||||
|
|
||||||
nsRefPtr<CommitHelper> helper = new CommitHelper(transaction, aRv);
|
nsRefPtr<CommitHelper> helper = new CommitHelper(transaction, aRv);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
||||||
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
|
ok(db.objectStoreNames.contains("foo"), "Has correct objectStore");
|
||||||
|
|
||||||
|
let originalRequest = request;
|
||||||
request = objectStore.add({}, 1);
|
request = objectStore.add({}, 1);
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
|
@ -88,10 +89,13 @@
|
||||||
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
is(db.objectStoreNames.length, 1, "Correct objectStoreNames length");
|
||||||
is(trans.error.name, "ConstraintError", "Right error");
|
is(trans.error.name, "ConstraintError", "Right error");
|
||||||
ok(trans.error === request.error, "Object identity holds");
|
ok(trans.error === request.error, "Object identity holds");
|
||||||
|
is(originalRequest.transaction, trans, "request.transaction should still be set");
|
||||||
|
|
||||||
event = yield;
|
event = yield;
|
||||||
is(event.type, "error", "Got request error event");
|
is(event.type, "error", "Got request error event");
|
||||||
|
is(event.target, originalRequest, "error event has right target");
|
||||||
is(event.target.error.name, "ConstraintError", "Right error");
|
is(event.target.error.name, "ConstraintError", "Right error");
|
||||||
|
is(originalRequest.transaction, null, "request.transaction should now be null");
|
||||||
|
|
||||||
let request = mozIndexedDB.open(window.location.pathname, 1);
|
let request = mozIndexedDB.open(window.location.pathname, 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
|
|
|
@ -7,7 +7,17 @@ var testGenerator = testSteps();
|
||||||
|
|
||||||
function executeSoon(aFun)
|
function executeSoon(aFun)
|
||||||
{
|
{
|
||||||
SimpleTest.executeSoon(aFun);
|
let comp = SpecialPowers.wrap(Components);
|
||||||
|
|
||||||
|
let thread = comp.classes["@mozilla.org/thread-manager;1"]
|
||||||
|
.getService(comp.interfaces.nsIThreadManager)
|
||||||
|
.mainThread;
|
||||||
|
|
||||||
|
thread.dispatch({
|
||||||
|
run: function() {
|
||||||
|
aFun();
|
||||||
|
}
|
||||||
|
}, Components.interfaces.nsIThread.DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearAllDatabases(callback) {
|
function clearAllDatabases(callback) {
|
||||||
|
|
|
@ -48,14 +48,11 @@ function testSteps()
|
||||||
event = yield;
|
event = yield;
|
||||||
is(event.type, "complete", "Got complete event");
|
is(event.type, "complete", "Got complete event");
|
||||||
|
|
||||||
// The database is still not fully open here.
|
|
||||||
try {
|
try {
|
||||||
db.transaction("foo");
|
db.transaction("foo");
|
||||||
ok(false, "Transactions should be disallowed now!");
|
ok(true, "Transactions should be allowed now!");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
ok(e instanceof DOMException, "Expect a DOMException");
|
ok(false, "Transactions should be allowed now!");
|
||||||
is(e.name, "InvalidStateError", "Expect an InvalidStateError");
|
|
||||||
is(e.code, DOMException.INVALID_STATE_ERR, "Expect an INVALID_STATE_ERR");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request.onsuccess = grabEventAndContinueHandler;
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|
|
@ -10,17 +10,69 @@ function testSteps()
|
||||||
let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
let request = mozIndexedDB.open(this.window ? window.location.pathname : "Splendid Test", 1);
|
||||||
request.onerror = errorHandler;
|
request.onerror = errorHandler;
|
||||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||||
|
request.onsuccess = unexpectedSuccessHandler;
|
||||||
let event = yield;
|
let event = yield;
|
||||||
|
|
||||||
let db = event.target.result;
|
let db = event.target.result;
|
||||||
db.onerror = errorHandler;
|
db.onerror = errorHandler;
|
||||||
|
|
||||||
event.target.onsuccess = continueToNextStep;
|
event.target.transaction.onerror = errorHandler;
|
||||||
|
event.target.transaction.oncomplete = grabEventAndContinueHandler;
|
||||||
|
|
||||||
db.createObjectStore("foo", { autoIncrement: true });
|
let os = db.createObjectStore("foo", { autoIncrement: true });
|
||||||
|
let index = os.createIndex("bar", "foo.bar");
|
||||||
|
event = yield;
|
||||||
|
|
||||||
|
is(request.transaction, event.target,
|
||||||
|
"request.transaction should still be set");
|
||||||
|
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
event = yield;
|
||||||
|
|
||||||
|
is(request.transaction, null, "request.transaction should be cleared");
|
||||||
|
|
||||||
|
let transaction = db.transaction("foo", "readwrite");
|
||||||
|
|
||||||
|
os = transaction.objectStore("foo");
|
||||||
|
// Place a request to keep the transaction alive long enough for our
|
||||||
|
// executeSoon.
|
||||||
|
let requestComplete = false;
|
||||||
|
|
||||||
|
let wasAbleToGrabObjectStoreOutsideOfCallback = false;
|
||||||
|
let wasAbleToGrabIndexOutsideOfCallback = false;
|
||||||
|
executeSoon(function() {
|
||||||
|
ok(!requestComplete, "Ordering is correct.");
|
||||||
|
wasAbleToGrabObjectStoreOutsideOfCallback = !!transaction.objectStore("foo");
|
||||||
|
wasAbleToGrabIndexOutsideOfCallback =
|
||||||
|
!!transaction.objectStore("foo").index("bar");
|
||||||
|
});
|
||||||
|
|
||||||
|
request = os.add({});
|
||||||
|
request.onerror = errorHandler;
|
||||||
|
request.onsuccess = grabEventAndContinueHandler;
|
||||||
|
|
||||||
|
event = yield;
|
||||||
|
|
||||||
|
requestComplete = true;
|
||||||
|
|
||||||
|
ok(wasAbleToGrabObjectStoreOutsideOfCallback,
|
||||||
|
"Should be able to get objectStore");
|
||||||
|
ok(wasAbleToGrabIndexOutsideOfCallback,
|
||||||
|
"Should be able to get index");
|
||||||
|
|
||||||
|
transaction.oncomplete = grabEventAndContinueHandler;
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
let transaction = db.transaction("foo");
|
try {
|
||||||
|
transaction.objectStore("foo");
|
||||||
|
ok(false, "Should have thrown!");
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
ok(e instanceof DOMException, "Got database exception.");
|
||||||
|
is(e.name, "InvalidStateError", "Good error.");
|
||||||
|
is(e.code, DOMException.INVALID_STATE_ERR, "Good error code.");
|
||||||
|
}
|
||||||
|
|
||||||
continueToNextStep();
|
continueToNextStep();
|
||||||
yield;
|
yield;
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ mOwner(owner)
|
||||||
// construct the URL we'll use later in calls to GetURL()
|
// construct the URL we'll use later in calls to GetURL()
|
||||||
NS_GetURLSpecFromFile(mTempFile, mFileURL);
|
NS_GetURLSpecFromFile(mTempFile, mFileURL);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
printf("File URL = %s\n", mFileURL.get());
|
printf("File URL = %s\n", mFileURL.get());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1636,7 +1636,7 @@ nsresult nsPluginHost::GetPlugin(const char *aMimeType, nsNPAPIPlugin** aPlugin)
|
||||||
("nsPluginHost::GetPlugin Begin mime=%s, plugin=%s\n",
|
("nsPluginHost::GetPlugin Begin mime=%s, plugin=%s\n",
|
||||||
aMimeType, pluginTag->mFileName.get()));
|
aMimeType, pluginTag->mFileName.get()));
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (aMimeType && !pluginTag->mFileName.IsEmpty())
|
if (aMimeType && !pluginTag->mFileName.IsEmpty())
|
||||||
printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName.get());
|
printf("For %s found plugin %s\n", aMimeType, pluginTag->mFileName.get());
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -219,7 +219,7 @@ void nsPluginNativeWindowGtk2::SetAllocation() {
|
||||||
nsresult nsPluginNativeWindowGtk2::CreateXtWindow() {
|
nsresult nsPluginNativeWindowGtk2::CreateXtWindow() {
|
||||||
NS_ASSERTION(!mSocketWidget,"Already created a socket widget!");
|
NS_ASSERTION(!mSocketWidget,"Already created a socket widget!");
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
printf("About to create new xtbin of %i X %i from %p...\n",
|
printf("About to create new xtbin of %i X %i from %p...\n",
|
||||||
width, height, (void*)window);
|
width, height, (void*)window);
|
||||||
#endif
|
#endif
|
||||||
|
@ -235,11 +235,11 @@ nsresult nsPluginNativeWindowGtk2::CreateXtWindow() {
|
||||||
|
|
||||||
gtk_widget_set_size_request(mSocketWidget, width, height);
|
gtk_widget_set_size_request(mSocketWidget, width, height);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
printf("About to show xtbin(%p)...\n", (void*)mSocketWidget); fflush(NULL);
|
printf("About to show xtbin(%p)...\n", (void*)mSocketWidget); fflush(NULL);
|
||||||
#endif
|
#endif
|
||||||
gtk_widget_show(mSocketWidget);
|
gtk_widget_show(mSocketWidget);
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
printf("completed gtk_widget_show(%p)\n", (void*)mSocketWidget); fflush(NULL);
|
printf("completed gtk_widget_show(%p)\n", (void*)mSocketWidget); fflush(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
|
||||||
pLibrary = *outLibrary;
|
pLibrary = *outLibrary;
|
||||||
#endif // MOZ_WIDGET_GTK2
|
#endif // MOZ_WIDGET_GTK2
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
printf("LoadPlugin() %s returned %lx\n",
|
printf("LoadPlugin() %s returned %lx\n",
|
||||||
libSpec.value.pathname, (unsigned long)pLibrary);
|
libSpec.value.pathname, (unsigned long)pLibrary);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "nsJSEnvironment.h"
|
#include "nsJSEnvironment.h"
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
#include "nspr.h" // PR_fprintf
|
#include "nspr.h" // PR_fprintf
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ nsJSEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||||
|
|
||||||
// mContext is the same context which event listener manager pushes
|
// mContext is the same context which event listener manager pushes
|
||||||
// to JS context stack.
|
// to JS context stack.
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
JSContext* cx = nsnull;
|
JSContext* cx = nsnull;
|
||||||
nsCOMPtr<nsIJSContextStack> stack =
|
nsCOMPtr<nsIJSContextStack> stack =
|
||||||
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
|
||||||
|
|
|
@ -65,6 +65,10 @@ interface nsIRILTelephonyCallback : nsISupports
|
||||||
[scriptable, uuid(8a711703-1ee5-4675-9d9a-0b188e944cfe)]
|
[scriptable, uuid(8a711703-1ee5-4675-9d9a-0b188e944cfe)]
|
||||||
interface nsIRILDataCallInfo : nsISupports
|
interface nsIRILDataCallInfo : nsISupports
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Current data call state, one of the
|
||||||
|
* nsINetworkInterface::NETWORK_STATE_* constants.
|
||||||
|
*/
|
||||||
readonly attribute unsigned long state;
|
readonly attribute unsigned long state;
|
||||||
readonly attribute AString cid;
|
readonly attribute AString cid;
|
||||||
readonly attribute AString apn;
|
readonly attribute AString apn;
|
||||||
|
@ -217,7 +221,7 @@ interface nsIRilContext : nsISupports
|
||||||
readonly attribute nsIDOMMozMobileConnectionInfo data;
|
readonly attribute nsIDOMMozMobileConnectionInfo data;
|
||||||
};
|
};
|
||||||
|
|
||||||
[scriptable, uuid(92bea0af-8d75-4592-87d0-1cab88e36904)]
|
[scriptable, uuid(8b649965-6687-46a8-88fa-a5495ce90735)]
|
||||||
interface nsIRadioInterfaceLayer : nsISupports
|
interface nsIRadioInterfaceLayer : nsISupports
|
||||||
{
|
{
|
||||||
const unsigned short CALL_STATE_UNKNOWN = 0;
|
const unsigned short CALL_STATE_UNKNOWN = 0;
|
||||||
|
@ -233,13 +237,6 @@ interface nsIRadioInterfaceLayer : nsISupports
|
||||||
const unsigned short CALL_STATE_DISCONNECTED = 10;
|
const unsigned short CALL_STATE_DISCONNECTED = 10;
|
||||||
const unsigned short CALL_STATE_INCOMING = 11;
|
const unsigned short CALL_STATE_INCOMING = 11;
|
||||||
|
|
||||||
// Keep consistent with GECKO_DATACALL_STATE_* values in ril_consts.js
|
|
||||||
const unsigned short DATACALL_STATE_UNKNOWN = 0;
|
|
||||||
const unsigned short DATACALL_STATE_CONNECTING = 1;
|
|
||||||
const unsigned short DATACALL_STATE_CONNECTED = 2;
|
|
||||||
const unsigned short DATACALL_STATE_DISCONNECTING = 3;
|
|
||||||
const unsigned short DATACALL_STATE_DISCONNECTED = 4;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates or deactivates radio power.
|
* Activates or deactivates radio power.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1756,7 +1756,7 @@ let RIL = {
|
||||||
* String containing PDP type to request. ("IP", "IPV6", ...)
|
* String containing PDP type to request. ("IP", "IPV6", ...)
|
||||||
*/
|
*/
|
||||||
setupDataCall: function setupDataCall(options) {
|
setupDataCall: function setupDataCall(options) {
|
||||||
let token = Buf.newParcel(REQUEST_SETUP_DATA_CALL);
|
let token = Buf.newParcel(REQUEST_SETUP_DATA_CALL, options);
|
||||||
Buf.writeUint32(7);
|
Buf.writeUint32(7);
|
||||||
Buf.writeString(options.radioTech.toString());
|
Buf.writeString(options.radioTech.toString());
|
||||||
Buf.writeString(DATACALL_PROFILE_DEFAULT.toString());
|
Buf.writeString(DATACALL_PROFILE_DEFAULT.toString());
|
||||||
|
@ -3297,41 +3297,43 @@ RIL[REQUEST_QUERY_CLIP] = null;
|
||||||
RIL[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
|
RIL[REQUEST_LAST_DATA_CALL_FAIL_CAUSE] = null;
|
||||||
|
|
||||||
RIL.readDataCall_v5 = function readDataCall_v5() {
|
RIL.readDataCall_v5 = function readDataCall_v5() {
|
||||||
return {
|
if (!options) {
|
||||||
cid: Buf.readUint32().toString(),
|
options = {};
|
||||||
active: Buf.readUint32(), // DATACALL_ACTIVE_*
|
}
|
||||||
type: Buf.readString(),
|
cid = Buf.readUint32().toString();
|
||||||
apn: Buf.readString(),
|
active = Buf.readUint32(); // DATACALL_ACTIVE_*
|
||||||
address: Buf.readString()
|
type = Buf.readString();
|
||||||
};
|
apn = Buf.readString();
|
||||||
|
address = Buf.readString();
|
||||||
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
RIL.readDataCall_v6 = function readDataCall_v6(obj) {
|
RIL.readDataCall_v6 = function readDataCall_v6(options) {
|
||||||
if (!obj) {
|
if (!options) {
|
||||||
obj = {};
|
options = {};
|
||||||
}
|
}
|
||||||
obj.status = Buf.readUint32(); // DATACALL_FAIL_*
|
options.status = Buf.readUint32(); // DATACALL_FAIL_*
|
||||||
if (!RILQUIRKS_DATACALLSTATE_NO_SUGGESTEDRETRYTIME) {
|
if (!RILQUIRKS_DATACALLSTATE_NO_SUGGESTEDRETRYTIME) {
|
||||||
obj.suggestedRetryTime = Buf.readUint32();
|
options.suggestedRetryTime = Buf.readUint32();
|
||||||
}
|
}
|
||||||
obj.cid = Buf.readUint32().toString();
|
options.cid = Buf.readUint32().toString();
|
||||||
obj.active = Buf.readUint32(); // DATACALL_ACTIVE_*
|
options.active = Buf.readUint32(); // DATACALL_ACTIVE_*
|
||||||
obj.type = Buf.readString();
|
options.type = Buf.readString();
|
||||||
obj.ifname = Buf.readString();
|
options.ifname = Buf.readString();
|
||||||
obj.ipaddr = Buf.readString();
|
options.ipaddr = Buf.readString();
|
||||||
obj.dns = Buf.readString();
|
options.dns = Buf.readString();
|
||||||
obj.gw = Buf.readString();
|
options.gw = Buf.readString();
|
||||||
if (obj.dns) {
|
if (options.dns) {
|
||||||
obj.dns = obj.dns.split(" ");
|
options.dns = options.dns.split(" ");
|
||||||
}
|
}
|
||||||
//TODO for now we only support one address and gateway
|
//TODO for now we only support one address and gateway
|
||||||
if (obj.ipaddr) {
|
if (options.ipaddr) {
|
||||||
obj.ipaddr = obj.ipaddr.split(" ")[0];
|
options.ipaddr = options.ipaddr.split(" ")[0];
|
||||||
}
|
}
|
||||||
if (obj.gw) {
|
if (options.gw) {
|
||||||
obj.gw = obj.gw.split(" ")[0];
|
options.gw = options.gw.split(" ")[0];
|
||||||
}
|
}
|
||||||
return obj;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
RIL[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length, options) {
|
RIL[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length, options) {
|
||||||
|
@ -3354,9 +3356,9 @@ RIL[REQUEST_DATA_CALL_LIST] = function REQUEST_DATA_CALL_LIST(length, options) {
|
||||||
for (let i = 0; i < num; i++) {
|
for (let i = 0; i < num; i++) {
|
||||||
let datacall;
|
let datacall;
|
||||||
if (version < 6) {
|
if (version < 6) {
|
||||||
datacall = this.readDataCall_v5();
|
datacall = this.readDataCall_v5(options);
|
||||||
} else {
|
} else {
|
||||||
datacall = this.readDataCall_v6();
|
datacall = this.readDataCall_v6(options);
|
||||||
}
|
}
|
||||||
datacalls[datacall.cid] = datacall;
|
datacalls[datacall.cid] = datacall;
|
||||||
}
|
}
|
||||||
|
|
|
@ -493,18 +493,14 @@ nsOutdentCommand::IsCommandEnabled(const char * aCommandName,
|
||||||
nsISupports *refCon,
|
nsISupports *refCon,
|
||||||
bool *outCmdEnabled)
|
bool *outCmdEnabled)
|
||||||
{
|
{
|
||||||
|
*outCmdEnabled = false;
|
||||||
|
|
||||||
nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
|
nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
|
||||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
|
if (editor) {
|
||||||
if (editor && htmlEditor)
|
nsresult rv = editor->GetIsSelectionEditable(outCmdEnabled);
|
||||||
{
|
|
||||||
bool canIndent, isEditable = false;
|
|
||||||
nsresult rv = editor->GetIsSelectionEditable(&isEditable);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
if (isEditable)
|
|
||||||
return htmlEditor->GetIndentState(&canIndent, outCmdEnabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*outCmdEnabled = false;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,12 +184,9 @@ nsSetDocumentStateCommand::IsCommandEnabled(const char * aCommandName,
|
||||||
nsISupports *refCon,
|
nsISupports *refCon,
|
||||||
bool *outCmdEnabled)
|
bool *outCmdEnabled)
|
||||||
{
|
{
|
||||||
|
// These commands are always enabled
|
||||||
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
||||||
nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
|
*outCmdEnabled = true;
|
||||||
if (editor)
|
|
||||||
return editor->GetIsSelectionEditable(outCmdEnabled);
|
|
||||||
|
|
||||||
*outCmdEnabled = false;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ NS_IMETHODIMP CreateElementTxn::Init(nsEditor *aEditor,
|
||||||
|
|
||||||
NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
char* nodename = ToNewCString(mTag);
|
char* nodename = ToNewCString(mTag);
|
||||||
|
@ -84,7 +84,7 @@ NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||||
// Try to insert formatting whitespace for the new node:
|
// Try to insert formatting whitespace for the new node:
|
||||||
mEditor->MarkNodeDirty(mNewNode);
|
mEditor->MarkNodeDirty(mNewNode);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf(" newNode = %p\n", static_cast<void*>(mNewNode.get()));
|
printf(" newNode = %p\n", static_cast<void*>(mNewNode.get()));
|
||||||
|
@ -134,7 +134,7 @@ NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP CreateElementTxn::UndoTransaction(void)
|
NS_IMETHODIMP CreateElementTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("Undo Create Element, mParent = %p, node = %p\n",
|
printf("Undo Create Element, mParent = %p, node = %p\n",
|
||||||
|
@ -152,7 +152,7 @@ NS_IMETHODIMP CreateElementTxn::UndoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP CreateElementTxn::RedoTransaction(void)
|
NS_IMETHODIMP CreateElementTxn::RedoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy) { printf("Redo Create Element\n"); }
|
if (gNoisy) { printf("Redo Create Element\n"); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
|
|
||||||
#include "DeleteElementTxn.h"
|
#include "DeleteElementTxn.h"
|
||||||
#include "nsSelectionState.h"
|
#include "nsSelectionState.h"
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
#include "nsIDOMElement.h"
|
#include "nsIDOMElement.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ NS_IMETHODIMP DeleteElementTxn::Init(nsIEditor *aEditor,
|
||||||
|
|
||||||
NS_IMETHODIMP DeleteElementTxn::DoTransaction(void)
|
NS_IMETHODIMP DeleteElementTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Do Delete Element element = %p\n",
|
printf("%p Do Delete Element element = %p\n",
|
||||||
|
@ -80,7 +80,7 @@ NS_IMETHODIMP DeleteElementTxn::DoTransaction(void)
|
||||||
|
|
||||||
if (!mParent) { return NS_OK; } // this is a no-op, there's no parent to delete mElement from
|
if (!mParent) { return NS_OK; } // this is a no-op, there's no parent to delete mElement from
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
// begin debug output
|
// begin debug output
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mElement);
|
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mElement);
|
||||||
nsAutoString elementTag(NS_LITERAL_STRING("text node"));
|
nsAutoString elementTag(NS_LITERAL_STRING("text node"));
|
||||||
|
@ -118,7 +118,7 @@ NS_IMETHODIMP DeleteElementTxn::DoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP DeleteElementTxn::UndoTransaction(void)
|
NS_IMETHODIMP DeleteElementTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Undo Delete Element element = %p, parent = %p\n",
|
printf("%p Undo Delete Element element = %p, parent = %p\n",
|
||||||
|
@ -131,7 +131,7 @@ NS_IMETHODIMP DeleteElementTxn::UndoTransaction(void)
|
||||||
if (!mParent) { return NS_OK; } // this is a legal state, the txn is a no-op
|
if (!mParent) { return NS_OK; } // this is a legal state, the txn is a no-op
|
||||||
if (!mElement) { return NS_ERROR_NULL_POINTER; }
|
if (!mElement) { return NS_ERROR_NULL_POINTER; }
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
// begin debug output
|
// begin debug output
|
||||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mElement);
|
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mElement);
|
||||||
nsAutoString elementTag(NS_LITERAL_STRING("text node"));
|
nsAutoString elementTag(NS_LITERAL_STRING("text node"));
|
||||||
|
@ -161,7 +161,7 @@ NS_IMETHODIMP DeleteElementTxn::UndoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP DeleteElementTxn::RedoTransaction(void)
|
NS_IMETHODIMP DeleteElementTxn::RedoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Redo Delete Element element = %p, parent = %p\n",
|
printf("%p Redo Delete Element element = %p, parent = %p\n",
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ NS_IMETHODIMP DeleteRangeTxn::Init(nsEditor *aEditor,
|
||||||
|
|
||||||
NS_IMETHODIMP DeleteRangeTxn::DoTransaction(void)
|
NS_IMETHODIMP DeleteRangeTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy) { printf("Do Delete Range\n"); }
|
if (gNoisy) { printf("Do Delete Range\n"); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ NS_IMETHODIMP DeleteRangeTxn::DoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP DeleteRangeTxn::UndoTransaction(void)
|
NS_IMETHODIMP DeleteRangeTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy) { printf("Undo Delete Range\n"); }
|
if (gNoisy) { printf("Undo Delete Range\n"); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ NS_IMETHODIMP DeleteRangeTxn::UndoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP DeleteRangeTxn::RedoTransaction(void)
|
NS_IMETHODIMP DeleteRangeTxn::RedoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy) { printf("Redo Delete Range\n"); }
|
if (gNoisy) { printf("Redo Delete Range\n"); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "nsIDOMNodeList.h"
|
#include "nsIDOMNodeList.h"
|
||||||
#include "nsReadableUtils.h"
|
#include "nsReadableUtils.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ NS_IMETHODIMP InsertElementTxn::Init(nsIDOMNode *aNode,
|
||||||
|
|
||||||
NS_IMETHODIMP InsertElementTxn::DoTransaction(void)
|
NS_IMETHODIMP InsertElementTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIContent>nodeAsContent = do_QueryInterface(mNode);
|
nsCOMPtr<nsIContent>nodeAsContent = do_QueryInterface(mNode);
|
||||||
|
@ -116,7 +116,7 @@ NS_IMETHODIMP InsertElementTxn::DoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP InsertElementTxn::UndoTransaction(void)
|
NS_IMETHODIMP InsertElementTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Undo Insert Element of %p into parent %p at offset %d\n",
|
printf("%p Undo Insert Element of %p into parent %p at offset %d\n",
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "nsISelection.h"
|
#include "nsISelection.h"
|
||||||
#include "EditAggregateTxn.h"
|
#include "EditAggregateTxn.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ NS_IMETHODIMP InsertTextTxn::Init(nsIDOMCharacterData *aElement,
|
||||||
|
|
||||||
NS_IMETHODIMP InsertTextTxn::DoTransaction(void)
|
NS_IMETHODIMP InsertTextTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("Do Insert Text element = %p\n",
|
printf("Do Insert Text element = %p\n",
|
||||||
|
@ -98,7 +98,7 @@ NS_IMETHODIMP InsertTextTxn::DoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP InsertTextTxn::UndoTransaction(void)
|
NS_IMETHODIMP InsertTextTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("Undo Insert Text element = %p\n",
|
printf("Undo Insert Text element = %p\n",
|
||||||
|
@ -133,7 +133,7 @@ NS_IMETHODIMP InsertTextTxn::Merge(nsITransaction *aTransaction, bool *aDidMerge
|
||||||
otherInsTxn->GetData(otherData);
|
otherInsTxn->GetData(otherData);
|
||||||
mStringToInsert += otherData;
|
mStringToInsert += otherData;
|
||||||
*aDidMerge = true;
|
*aDidMerge = true;
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("InsertTextTxn assimilated %p\n",
|
printf("InsertTextTxn assimilated %p\n",
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "nsIDOMNodeList.h"
|
#include "nsIDOMNodeList.h"
|
||||||
#include "nsIDOMCharacterData.h"
|
#include "nsIDOMCharacterData.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ NS_IMETHODIMP JoinElementTxn::Init(nsEditor *aEditor,
|
||||||
// After DoTransaction() and RedoTransaction(), the left node is removed from the content tree and right node remains.
|
// After DoTransaction() and RedoTransaction(), the left node is removed from the content tree and right node remains.
|
||||||
NS_IMETHODIMP JoinElementTxn::DoTransaction(void)
|
NS_IMETHODIMP JoinElementTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Do Join of %p and %p\n",
|
printf("%p Do Join of %p and %p\n",
|
||||||
|
@ -108,7 +108,7 @@ NS_IMETHODIMP JoinElementTxn::DoTransaction(void)
|
||||||
// and re-inserted mLeft?
|
// and re-inserted mLeft?
|
||||||
NS_IMETHODIMP JoinElementTxn::UndoTransaction(void)
|
NS_IMETHODIMP JoinElementTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Undo Join, right node = %p\n",
|
printf("%p Undo Join, right node = %p\n",
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "nsISelection.h"
|
#include "nsISelection.h"
|
||||||
#include "nsIDOMCharacterData.h"
|
#include "nsIDOMCharacterData.h"
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
static bool gNoisy = false;
|
static bool gNoisy = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ NS_IMETHODIMP SplitElementTxn::Init(nsEditor *aEditor,
|
||||||
|
|
||||||
NS_IMETHODIMP SplitElementTxn::DoTransaction(void)
|
NS_IMETHODIMP SplitElementTxn::DoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("%p Do Split of node %p offset %d\n",
|
printf("%p Do Split of node %p offset %d\n",
|
||||||
|
@ -72,7 +72,7 @@ NS_IMETHODIMP SplitElementTxn::DoTransaction(void)
|
||||||
NS_ENSURE_TRUE(mNewLeftNode, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(mNewLeftNode, NS_ERROR_NULL_POINTER);
|
||||||
mEditor->MarkNodeDirty(mExistingRightNode);
|
mEditor->MarkNodeDirty(mExistingRightNode);
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf(" created left node = %p\n",
|
printf(" created left node = %p\n",
|
||||||
|
@ -108,7 +108,7 @@ NS_IMETHODIMP SplitElementTxn::DoTransaction(void)
|
||||||
|
|
||||||
NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
|
NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy) {
|
if (gNoisy) {
|
||||||
printf("%p Undo Split of existing node %p and new node %p offset %d\n",
|
printf("%p Undo Split of existing node %p and new node %p offset %d\n",
|
||||||
static_cast<void*>(this),
|
static_cast<void*>(this),
|
||||||
|
@ -125,7 +125,7 @@ NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
|
||||||
|
|
||||||
// this assumes Do inserted the new node in front of the prior existing node
|
// this assumes Do inserted the new node in front of the prior existing node
|
||||||
nsresult result = mEditor->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent, false);
|
nsresult result = mEditor->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent, false);
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("** after join left child node %p into right node %p\n",
|
printf("** after join left child node %p into right node %p\n",
|
||||||
|
@ -156,7 +156,7 @@ NS_IMETHODIMP SplitElementTxn::RedoTransaction(void)
|
||||||
return NS_ERROR_NOT_INITIALIZED;
|
return NS_ERROR_NOT_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy) {
|
if (gNoisy) {
|
||||||
printf("%p Redo Split of existing node %p and new node %p offset %d\n",
|
printf("%p Redo Split of existing node %p and new node %p offset %d\n",
|
||||||
static_cast<void*>(this),
|
static_cast<void*>(this),
|
||||||
|
@ -174,7 +174,7 @@ NS_IMETHODIMP SplitElementTxn::RedoTransaction(void)
|
||||||
if (rightNodeAsText)
|
if (rightNodeAsText)
|
||||||
{
|
{
|
||||||
result = rightNodeAsText->DeleteData(0, mOffset);
|
result = rightNodeAsText->DeleteData(0, mOffset);
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("** after delete of text in right text node %p offset %d\n",
|
printf("** after delete of text in right text node %p offset %d\n",
|
||||||
|
@ -199,7 +199,7 @@ NS_IMETHODIMP SplitElementTxn::RedoTransaction(void)
|
||||||
if (NS_SUCCEEDED(result))
|
if (NS_SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
result = mNewLeftNode->AppendChild(child, getter_AddRefs(resultNode));
|
result = mNewLeftNode->AppendChild(child, getter_AddRefs(resultNode));
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("** move child node %p from right node %p to left node %p\n",
|
printf("** move child node %p from right node %p to left node %p\n",
|
||||||
|
@ -215,7 +215,7 @@ NS_IMETHODIMP SplitElementTxn::RedoTransaction(void)
|
||||||
}
|
}
|
||||||
// second, re-insert the left node into the tree
|
// second, re-insert the left node into the tree
|
||||||
result = mParent->InsertBefore(mNewLeftNode, mExistingRightNode, getter_AddRefs(resultNode));
|
result = mParent->InsertBefore(mNewLeftNode, mExistingRightNode, getter_AddRefs(resultNode));
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
if (gNoisy)
|
if (gNoisy)
|
||||||
{
|
{
|
||||||
printf("** reinsert left child node %p before right node %p\n",
|
printf("** reinsert left child node %p before right node %p\n",
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function boom()
|
||||||
|
{
|
||||||
|
var r = document.createRange();
|
||||||
|
r.setEnd(document.createTextNode("x"), 0);
|
||||||
|
window.getSelection().addRange(r);
|
||||||
|
document.execCommand("inserthtml", false, "y");
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body contenteditable="true" onload="boom();"></body>
|
||||||
|
</html>
|
|
@ -11,4 +11,5 @@ load 636074-1.html
|
||||||
load 713427-1.html
|
load 713427-1.html
|
||||||
load 713427-2.xhtml
|
load 713427-2.xhtml
|
||||||
load 762183.html
|
load 762183.html
|
||||||
|
load 766360.html
|
||||||
load 766413.html
|
load 766413.html
|
||||||
|
|
|
@ -4377,25 +4377,25 @@ NS_IMETHODIMP
|
||||||
nsEditor::DeleteSelectionAndCreateNode(const nsAString& aTag,
|
nsEditor::DeleteSelectionAndCreateNode(const nsAString& aTag,
|
||||||
nsIDOMNode ** aNewNode)
|
nsIDOMNode ** aNewNode)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIDOMNode> parentSelectedNode;
|
nsresult result = DeleteSelectionAndPrepareToCreateNode();
|
||||||
PRInt32 offsetOfNewNode;
|
|
||||||
nsresult result = DeleteSelectionAndPrepareToCreateNode(parentSelectedNode,
|
|
||||||
offsetOfNewNode);
|
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
NS_ENSURE_SUCCESS(result, result);
|
||||||
|
|
||||||
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
|
nsCOMPtr<nsINode> node = selection->GetAnchorNode();
|
||||||
|
PRInt32 offset = selection->GetAnchorOffset();
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> newNode;
|
nsCOMPtr<nsIDOMNode> newNode;
|
||||||
result = CreateNode(aTag, parentSelectedNode, offsetOfNewNode,
|
result = CreateNode(aTag, node->AsDOMNode(), offset,
|
||||||
getter_AddRefs(newNode));
|
getter_AddRefs(newNode));
|
||||||
// XXX: ERROR_HANDLING check result, and make sure aNewNode is set correctly in success/failure cases
|
// XXX: ERROR_HANDLING check result, and make sure aNewNode is set correctly
|
||||||
|
// in success/failure cases
|
||||||
*aNewNode = newNode;
|
*aNewNode = newNode;
|
||||||
NS_IF_ADDREF(*aNewNode);
|
NS_IF_ADDREF(*aNewNode);
|
||||||
|
|
||||||
// we want the selection to be just after the new node
|
// we want the selection to be just after the new node
|
||||||
nsCOMPtr<nsISelection> selection;
|
return selection->Collapse(node, offset + 1);
|
||||||
result = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
|
||||||
return selection->Collapse(parentSelectedNode, offsetOfNewNode+1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4442,86 +4442,55 @@ nsEditor::IsIMEComposing() {
|
||||||
return mIsIMEComposing;
|
return mIsIMEComposing;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
nsEditor::DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode, PRInt32& offsetOfNewNode)
|
nsEditor::DeleteSelectionAndPrepareToCreateNode()
|
||||||
{
|
{
|
||||||
nsresult result=NS_ERROR_NOT_INITIALIZED;
|
nsresult res;
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
result = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
if (!selection->Collapsed()) {
|
if (!selection->Collapsed()) {
|
||||||
result = DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
|
res = DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
|
||||||
if (NS_FAILED(result)) {
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
// get the new selection
|
|
||||||
result = GetSelection(getter_AddRefs(selection));
|
|
||||||
if (NS_FAILED(result)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> selectedNode;
|
MOZ_ASSERT(selection->Collapsed(),
|
||||||
selection->GetAnchorNode(getter_AddRefs(selectedNode));
|
"Selection not collapsed after delete");
|
||||||
// no selection is ok.
|
}
|
||||||
// if there is a selection, it must be collapsed
|
|
||||||
if (selectedNode && !selection->Collapsed()) {
|
// If the selection is a chardata node, split it if necessary and compute
|
||||||
result = selection->CollapseToEnd();
|
// where to put the new node
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
nsCOMPtr<nsINode> node = selection->GetAnchorNode();
|
||||||
|
MOZ_ASSERT(node, "Selection has no ranges in it");
|
||||||
|
|
||||||
|
if (node && node->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||||
|
NS_ASSERTION(node->GetNodeParent(),
|
||||||
|
"It's impossible to insert into chardata with no parent -- "
|
||||||
|
"fix the caller");
|
||||||
|
NS_ENSURE_STATE(node->GetNodeParent());
|
||||||
|
|
||||||
|
PRInt32 offset = selection->GetAnchorOffset();
|
||||||
|
|
||||||
|
if (offset == 0) {
|
||||||
|
res = selection->Collapse(node->GetNodeParent(),
|
||||||
|
node->GetNodeParent()->IndexOf(node));
|
||||||
|
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||||
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
|
} else if (offset == (PRInt32)node->Length()) {
|
||||||
|
res = selection->Collapse(node->GetNodeParent(),
|
||||||
|
node->GetNodeParent()->IndexOf(node) + 1);
|
||||||
|
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||||
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
|
} else {
|
||||||
|
nsCOMPtr<nsIDOMNode> tmp;
|
||||||
|
res = SplitNode(node->AsDOMNode(), offset, getter_AddRefs(tmp));
|
||||||
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
|
res = selection->Collapse(node->GetNodeParent(),
|
||||||
|
node->GetNodeParent()->IndexOf(node));
|
||||||
|
MOZ_ASSERT(NS_SUCCEEDED(res));
|
||||||
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// split the selected node
|
return NS_OK;
|
||||||
PRInt32 offsetOfSelectedNode;
|
|
||||||
result = selection->GetAnchorNode(getter_AddRefs(parentSelectedNode));
|
|
||||||
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(selection->GetAnchorOffset(&offsetOfSelectedNode)) && parentSelectedNode)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMNode> selectedNode;
|
|
||||||
PRUint32 selectedNodeContentCount=0;
|
|
||||||
nsCOMPtr<nsIDOMCharacterData>selectedParentNodeAsText;
|
|
||||||
selectedParentNodeAsText = do_QueryInterface(parentSelectedNode);
|
|
||||||
|
|
||||||
offsetOfNewNode = offsetOfSelectedNode;
|
|
||||||
|
|
||||||
/* if the selection is a text node, split the text node if necessary
|
|
||||||
and compute where to put the new node
|
|
||||||
*/
|
|
||||||
if (selectedParentNodeAsText)
|
|
||||||
{
|
|
||||||
PRInt32 indexOfTextNodeInParent;
|
|
||||||
selectedNode = do_QueryInterface(parentSelectedNode);
|
|
||||||
selectedNode->GetParentNode(getter_AddRefs(parentSelectedNode));
|
|
||||||
selectedParentNodeAsText->GetLength(&selectedNodeContentCount);
|
|
||||||
GetChildOffset(selectedNode, parentSelectedNode, indexOfTextNodeInParent);
|
|
||||||
|
|
||||||
if ((offsetOfSelectedNode!=0) && (((PRUint32)offsetOfSelectedNode)!=selectedNodeContentCount))
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMNode> newSiblingNode;
|
|
||||||
result = SplitNode(selectedNode, offsetOfSelectedNode, getter_AddRefs(newSiblingNode));
|
|
||||||
// now get the node's offset in its parent, and insert the new tag there
|
|
||||||
if (NS_SUCCEEDED(result)) {
|
|
||||||
result = GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // determine where to insert the new node
|
|
||||||
if (0==offsetOfSelectedNode) {
|
|
||||||
offsetOfNewNode = indexOfTextNodeInParent; // insert new node as previous sibling to selection parent
|
|
||||||
}
|
|
||||||
else { // insert new node as last child
|
|
||||||
GetChildOffset(selectedNode, parentSelectedNode, offsetOfNewNode);
|
|
||||||
offsetOfNewNode++; // offsets are 0-based, and we need the index of the new node
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Here's where the new node was inserted
|
|
||||||
}
|
|
||||||
#ifdef DEBUG
|
|
||||||
else {
|
|
||||||
printf("InsertLineBreak into an empty document is not yet supported\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -314,8 +314,15 @@ protected:
|
||||||
nsIDOMNode *aRightNode,
|
nsIDOMNode *aRightNode,
|
||||||
JoinElementTxn **aTxn);
|
JoinElementTxn **aTxn);
|
||||||
|
|
||||||
NS_IMETHOD DeleteSelectionAndPrepareToCreateNode(nsCOMPtr<nsIDOMNode> &parentSelectedNode,
|
/**
|
||||||
PRInt32& offsetOfNewNode);
|
* This method first deletes the selection, if it's not collapsed. Then if
|
||||||
|
* the selection lies in a CharacterData node, it splits it. If the
|
||||||
|
* selection is at this point collapsed in a CharacterData node, it's
|
||||||
|
* adjusted to be collapsed right before or after the node instead (which is
|
||||||
|
* always possible, since the node was split).
|
||||||
|
*/
|
||||||
|
nsresult DeleteSelectionAndPrepareToCreateNode();
|
||||||
|
|
||||||
|
|
||||||
// called after a transaction is done successfully
|
// called after a transaction is done successfully
|
||||||
NS_IMETHOD DoAfterDoTransaction(nsITransaction *aTxn);
|
NS_IMETHOD DoAfterDoTransaction(nsITransaction *aTxn);
|
||||||
|
|
|
@ -527,68 +527,60 @@ nsSwitchTextDirectionCommand::GetCommandStateParams(const char *aCommandName,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDeleteCommand::IsCommandEnabled(const char * aCommandName,
|
nsDeleteCommand::IsCommandEnabled(const char* aCommandName,
|
||||||
nsISupports *aCommandRefCon,
|
nsISupports* aCommandRefCon,
|
||||||
bool *outCmdEnabled)
|
bool* outCmdEnabled)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
NS_ENSURE_ARG_POINTER(outCmdEnabled);
|
||||||
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
|
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
|
||||||
*outCmdEnabled = false;
|
*outCmdEnabled = false;
|
||||||
|
|
||||||
// we can delete when we can cut
|
|
||||||
NS_ENSURE_TRUE(editor, NS_OK);
|
NS_ENSURE_TRUE(editor, NS_OK);
|
||||||
|
|
||||||
bool isEditable = false;
|
// We can generally delete whenever the selection is editable. However,
|
||||||
nsresult rv = editor->GetIsSelectionEditable(&isEditable);
|
// cmd_delete doesn't make sense if the selection is collapsed because it's
|
||||||
|
// directionless, which is the same condition under which we can't cut.
|
||||||
|
nsresult rv = editor->GetIsSelectionEditable(outCmdEnabled);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (!isEditable)
|
if (!nsCRT::strcmp("cmd_delete", aCommandName) && *outCmdEnabled) {
|
||||||
return NS_OK;
|
rv = editor->CanCut(outCmdEnabled);
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_delete"))
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
return editor->CanCut(outCmdEnabled);
|
}
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_forwardDelete"))
|
|
||||||
return editor->CanCut(outCmdEnabled);
|
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_deleteCharBackward"))
|
|
||||||
*outCmdEnabled = true;
|
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_deleteCharForward"))
|
|
||||||
*outCmdEnabled = true;
|
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_deleteWordBackward"))
|
|
||||||
*outCmdEnabled = true;
|
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_deleteWordForward"))
|
|
||||||
*outCmdEnabled = true;
|
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_deleteToBeginningOfLine"))
|
|
||||||
*outCmdEnabled = true;
|
|
||||||
else if (!nsCRT::strcmp(aCommandName,"cmd_deleteToEndOfLine"))
|
|
||||||
*outCmdEnabled = true;
|
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDeleteCommand::DoCommand(const char *aCommandName, nsISupports *aCommandRefCon)
|
nsDeleteCommand::DoCommand(const char* aCommandName,
|
||||||
|
nsISupports* aCommandRefCon)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
|
nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
|
||||||
NS_ENSURE_TRUE(editor, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(editor, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsIEditor::EDirection deleteDir = nsIEditor::eNone;
|
nsIEditor::EDirection deleteDir = nsIEditor::eNone;
|
||||||
|
|
||||||
if (!nsCRT::strcmp("cmd_delete",aCommandName))
|
if (!nsCRT::strcmp("cmd_delete", aCommandName)) {
|
||||||
|
// Really this should probably be eNone, but it only makes a difference if
|
||||||
|
// the selection is collapsed, and then this command is disabled. So let's
|
||||||
|
// keep it as it always was to avoid breaking things.
|
||||||
deleteDir = nsIEditor::ePrevious;
|
deleteDir = nsIEditor::ePrevious;
|
||||||
else if (!nsCRT::strcmp("cmd_forwardDelete", aCommandName))
|
} else if (!nsCRT::strcmp("cmd_deleteCharForward", aCommandName)) {
|
||||||
deleteDir = nsIEditor::eNext;
|
deleteDir = nsIEditor::eNext;
|
||||||
else if (!nsCRT::strcmp("cmd_deleteCharBackward",aCommandName))
|
} else if (!nsCRT::strcmp("cmd_deleteCharBackward", aCommandName)) {
|
||||||
deleteDir = nsIEditor::ePrevious;
|
deleteDir = nsIEditor::ePrevious;
|
||||||
else if (!nsCRT::strcmp("cmd_deleteCharForward",aCommandName))
|
} else if (!nsCRT::strcmp("cmd_deleteWordBackward", aCommandName)) {
|
||||||
deleteDir = nsIEditor::eNext;
|
|
||||||
else if (!nsCRT::strcmp("cmd_deleteWordBackward",aCommandName))
|
|
||||||
deleteDir = nsIEditor::ePreviousWord;
|
deleteDir = nsIEditor::ePreviousWord;
|
||||||
else if (!nsCRT::strcmp("cmd_deleteWordForward",aCommandName))
|
} else if (!nsCRT::strcmp("cmd_deleteWordForward", aCommandName)) {
|
||||||
deleteDir = nsIEditor::eNextWord;
|
deleteDir = nsIEditor::eNextWord;
|
||||||
else if (!nsCRT::strcmp("cmd_deleteToBeginningOfLine",aCommandName))
|
} else if (!nsCRT::strcmp("cmd_deleteToBeginningOfLine", aCommandName)) {
|
||||||
deleteDir = nsIEditor::eToBeginningOfLine;
|
deleteDir = nsIEditor::eToBeginningOfLine;
|
||||||
else if (!nsCRT::strcmp("cmd_deleteToEndOfLine",aCommandName))
|
} else if (!nsCRT::strcmp("cmd_deleteToEndOfLine", aCommandName)) {
|
||||||
deleteDir = nsIEditor::eToEndOfLine;
|
deleteDir = nsIEditor::eToEndOfLine;
|
||||||
|
} else {
|
||||||
|
MOZ_NOT_REACHED("Unrecognized nsDeleteCommand");
|
||||||
|
}
|
||||||
|
|
||||||
return editor->DeleteSelection(deleteDir, nsIEditor::eStrip);
|
return editor->DeleteSelection(deleteDir, nsIEditor::eStrip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,6 @@ nsresult nsEditorController::RegisterEditingCommands(nsIControllerCommandTable *
|
||||||
NS_REGISTER_ONE_COMMAND(nsSwitchTextDirectionCommand, "cmd_switchTextDirection");
|
NS_REGISTER_ONE_COMMAND(nsSwitchTextDirectionCommand, "cmd_switchTextDirection");
|
||||||
|
|
||||||
NS_REGISTER_FIRST_COMMAND(nsDeleteCommand, "cmd_delete");
|
NS_REGISTER_FIRST_COMMAND(nsDeleteCommand, "cmd_delete");
|
||||||
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_forwardDelete");
|
|
||||||
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteCharBackward");
|
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteCharBackward");
|
||||||
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteCharForward");
|
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteCharForward");
|
||||||
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteWordBackward");
|
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteWordBackward");
|
||||||
|
|
|
@ -25,7 +25,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=408231
|
||||||
["createlink", "true"],
|
["createlink", "true"],
|
||||||
["cut", "false"],
|
["cut", "false"],
|
||||||
["decreasefontsize", "true"],
|
["decreasefontsize", "true"],
|
||||||
["delete", "false"],
|
["delete", "true"],
|
||||||
["fontname", "true"],
|
["fontname", "true"],
|
||||||
["fontsize", "true"],
|
["fontsize", "true"],
|
||||||
["formatblock", "true"],
|
["formatblock", "true"],
|
||||||
|
@ -44,7 +44,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=408231
|
||||||
["justifyfull", "true"],
|
["justifyfull", "true"],
|
||||||
["justifyleft", "true"],
|
["justifyleft", "true"],
|
||||||
["justifyright", "true"],
|
["justifyright", "true"],
|
||||||
["outdent", "false"],
|
["outdent", "true"],
|
||||||
//["paste", "true"],
|
//["paste", "true"],
|
||||||
["redo", "false"],
|
["redo", "false"],
|
||||||
["removeformat", "true"],
|
["removeformat", "true"],
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#ifndef __TextEditorTest_h__
|
#ifndef __TextEditorTest_h__
|
||||||
#define __TextEditorTest_h__
|
#define __TextEditorTest_h__
|
||||||
|
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIEditor.h"
|
#include "nsIEditor.h"
|
||||||
|
@ -35,6 +35,6 @@ protected:
|
||||||
nsCOMPtr<nsIEditor> mEditor;
|
nsCOMPtr<nsIEditor> mEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NS_DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function boom()
|
||||||
|
{
|
||||||
|
window.getSelection().removeAllRanges();
|
||||||
|
var r = document.createRange();
|
||||||
|
r.setStart(document.getElementById("x"), 1);
|
||||||
|
r.setEnd(document.getElementById("y"), 0);
|
||||||
|
window.getSelection().addRange(r);
|
||||||
|
document.execCommand("insertorderedlist", false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="boom();"><div id="x" contenteditable="true">a</div><div id="y" contenteditable="true"></div></body>
|
||||||
|
</html>
|
|
@ -28,5 +28,6 @@ load 682650-1.html
|
||||||
load 716456-1.html
|
load 716456-1.html
|
||||||
load 759748.html
|
load 759748.html
|
||||||
load 761861.html
|
load 761861.html
|
||||||
load 766795.html
|
|
||||||
load 766305.html
|
load 766305.html
|
||||||
|
load 766387.html
|
||||||
|
load 766795.html
|
||||||
|
|
|
@ -361,7 +361,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||||
|
|
||||||
if (!cellSelectionMode)
|
if (!cellSelectionMode)
|
||||||
{
|
{
|
||||||
rv = DeleteSelectionAndPrepareToCreateNode(parentNode, offsetOfNewNode);
|
rv = DeleteSelectionAndPrepareToCreateNode();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
// pasting does not inherit local inline styles
|
// pasting does not inherit local inline styles
|
||||||
|
|
|
@ -1720,9 +1720,7 @@ nsHTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, bool aDeleteSele
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMNode> tempNode;
|
nsresult result = DeleteSelectionAndPrepareToCreateNode();
|
||||||
PRInt32 tempOffset;
|
|
||||||
nsresult result = DeleteSelectionAndPrepareToCreateNode(tempNode,tempOffset);
|
|
||||||
NS_ENSURE_SUCCESS(result, result);
|
NS_ENSURE_SUCCESS(result, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3598,6 +3596,36 @@ nsHTMLEditor::IsModifiableNode(nsINode *aNode)
|
||||||
return !aNode || aNode->IsEditable();
|
return !aNode || aNode->IsEditable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHTMLEditor::GetIsSelectionEditable(bool* aIsSelectionEditable)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aIsSelectionEditable);
|
||||||
|
|
||||||
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
|
// Per the editing spec as of June 2012: we have to have a selection whose
|
||||||
|
// start and end nodes are editable, and which share an ancestor editing
|
||||||
|
// host. (Bug 766387.)
|
||||||
|
*aIsSelectionEditable = selection->GetRangeCount() &&
|
||||||
|
selection->GetAnchorNode()->IsEditable() &&
|
||||||
|
selection->GetFocusNode()->IsEditable();
|
||||||
|
|
||||||
|
if (*aIsSelectionEditable) {
|
||||||
|
nsINode* commonAncestor =
|
||||||
|
selection->GetAnchorFocusRange()->GetCommonAncestor();
|
||||||
|
while (commonAncestor && !commonAncestor->IsEditable()) {
|
||||||
|
commonAncestor = commonAncestor->GetNodeParent();
|
||||||
|
}
|
||||||
|
if (!commonAncestor) {
|
||||||
|
// No editable common ancestor
|
||||||
|
*aIsSelectionEditable = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static nsresult
|
static nsresult
|
||||||
SetSelectionAroundHeadChildren(nsISelection* aSelection,
|
SetSelectionAroundHeadChildren(nsISelection* aSelection,
|
||||||
nsIWeakReference* aDocWeak)
|
nsIWeakReference* aDocWeak)
|
||||||
|
|
|
@ -310,6 +310,8 @@ public:
|
||||||
NS_IMETHOD_(bool) IsModifiableNode(nsIDOMNode *aNode);
|
NS_IMETHOD_(bool) IsModifiableNode(nsIDOMNode *aNode);
|
||||||
virtual bool IsModifiableNode(nsINode *aNode);
|
virtual bool IsModifiableNode(nsINode *aNode);
|
||||||
|
|
||||||
|
NS_IMETHOD GetIsSelectionEditable(bool* aIsSelectionEditable);
|
||||||
|
|
||||||
NS_IMETHOD SelectAll();
|
NS_IMETHOD SelectAll();
|
||||||
|
|
||||||
NS_IMETHOD GetRootElement(nsIDOMElement **aRootElement);
|
NS_IMETHOD GetRootElement(nsIDOMElement **aRootElement);
|
||||||
|
|
|
@ -283,9 +283,6 @@ const knownFailures = {
|
||||||
"QE-Proposed-INSERTLINEBREAK_TEXT-1-dM": true,
|
"QE-Proposed-INSERTLINEBREAK_TEXT-1-dM": true,
|
||||||
"QE-Proposed-INSERTLINEBREAK_TEXT-1-body": true,
|
"QE-Proposed-INSERTLINEBREAK_TEXT-1-body": true,
|
||||||
"QE-Proposed-INSERTLINEBREAK_TEXT-1-div": true,
|
"QE-Proposed-INSERTLINEBREAK_TEXT-1-div": true,
|
||||||
"QE-Proposed-OUTDENT_TEXT-1-dM": true,
|
|
||||||
"QE-Proposed-OUTDENT_TEXT-1-body": true,
|
|
||||||
"QE-Proposed-OUTDENT_TEXT-1-div": true,
|
|
||||||
"QE-Proposed-CREATEBOOKMARK_TEXT-1-dM": true,
|
"QE-Proposed-CREATEBOOKMARK_TEXT-1-dM": true,
|
||||||
"QE-Proposed-CREATEBOOKMARK_TEXT-1-body": true,
|
"QE-Proposed-CREATEBOOKMARK_TEXT-1-body": true,
|
||||||
"QE-Proposed-CREATEBOOKMARK_TEXT-1-div": true,
|
"QE-Proposed-CREATEBOOKMARK_TEXT-1-div": true,
|
||||||
|
|
|
@ -26,11 +26,11 @@ addLoadEvent(function() {
|
||||||
document.querySelector("input").focus();
|
document.querySelector("input").focus();
|
||||||
var threw = false;
|
var threw = false;
|
||||||
try {
|
try {
|
||||||
document.execCommand("inserthtml", null, "<span>f" + "oo</span>");
|
is(document.execCommand("inserthtml", null, "<span>f" + "oo</span>"),
|
||||||
|
false, "The insertHTML command should return false");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
threw = true;
|
ok(false, "insertHTML should not throw here");
|
||||||
}
|
}
|
||||||
ok(threw, "The inserthtml command should fail");
|
|
||||||
is(document.querySelectorAll("span").length, 0, "No span element should be injected inside the page");
|
is(document.querySelectorAll("span").length, 0, "No span element should be injected inside the page");
|
||||||
is(document.body.innerHTML.indexOf("f" + "oo"), -1, "No text should be injected inside the page");
|
is(document.body.innerHTML.indexOf("f" + "oo"), -1, "No text should be injected inside the page");
|
||||||
SimpleTest.finish();
|
SimpleTest.finish();
|
||||||
|
|
|
@ -32,13 +32,24 @@ SimpleTest.waitForFocus(runTests);
|
||||||
|
|
||||||
var gBlock1, gBlock2;
|
var gBlock1, gBlock2;
|
||||||
|
|
||||||
function IsCommandEnabled(command, alwaysEnabled) {
|
var alwaysEnabledCommands = [
|
||||||
|
"contentReadOnly",
|
||||||
|
"copy",
|
||||||
|
"enableInlineTableEditing",
|
||||||
|
"enableObjectResizing",
|
||||||
|
"insertBrOnReturn",
|
||||||
|
"selectAll",
|
||||||
|
"styleWithCSS",
|
||||||
|
];
|
||||||
|
|
||||||
|
function IsCommandEnabled(command) {
|
||||||
var enabled;
|
var enabled;
|
||||||
|
|
||||||
// non-editable div: should return false unless alwaysEnabled
|
// non-editable div: should return false unless alwaysEnabled
|
||||||
window.getSelection().selectAllChildren(gBlock1);
|
window.getSelection().selectAllChildren(gBlock1);
|
||||||
enabled = document.queryCommandEnabled(command);
|
enabled = document.queryCommandEnabled(command);
|
||||||
is(enabled, alwaysEnabled, "'" + command + "' should not be enabled on a non-editable block.");
|
is(enabled, alwaysEnabledCommands.indexOf(command) != -1,
|
||||||
|
"'" + command + "' should not be enabled on a non-editable block.");
|
||||||
|
|
||||||
// editable div: should return true
|
// editable div: should return true
|
||||||
window.getSelection().selectAllChildren(gBlock2);
|
window.getSelection().selectAllChildren(gBlock2);
|
||||||
|
@ -67,15 +78,15 @@ function runTests() {
|
||||||
];
|
];
|
||||||
document.execCommand("styleWithCSS", false, false);
|
document.execCommand("styleWithCSS", false, false);
|
||||||
for (i = 0; i < commands.length; i++)
|
for (i = 0; i < commands.length; i++)
|
||||||
IsCommandEnabled(commands[i], commands[i] == "selectAll");
|
IsCommandEnabled(commands[i]);
|
||||||
document.execCommand("styleWithCSS", false, true);
|
document.execCommand("styleWithCSS", false, true);
|
||||||
for (i = 0; i < commands.length; i++)
|
for (i = 0; i < commands.length; i++)
|
||||||
IsCommandEnabled(commands[i], commands[i] == "selectAll");
|
IsCommandEnabled(commands[i]);
|
||||||
|
|
||||||
// Mozilla-specific stuff
|
// Mozilla-specific stuff
|
||||||
commands = ["enableInlineTableEditing", "enableObjectResizing", "insertBrOnReturn"];
|
commands = ["enableInlineTableEditing", "enableObjectResizing", "insertBrOnReturn"];
|
||||||
for (i = 0; i < commands.length; i++)
|
for (i = 0; i < commands.length; i++)
|
||||||
IsCommandEnabled(commands[i], false);
|
IsCommandEnabled(commands[i]);
|
||||||
|
|
||||||
// cut/copy/paste -- SpecialPowers required
|
// cut/copy/paste -- SpecialPowers required
|
||||||
SpecialPowers.setCharPref("capability.policy.policynames", "allowclipboard");
|
SpecialPowers.setCharPref("capability.policy.policynames", "allowclipboard");
|
||||||
|
@ -84,7 +95,7 @@ function runTests() {
|
||||||
SpecialPowers.setCharPref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");
|
SpecialPowers.setCharPref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");
|
||||||
commands = ["cut", "paste", "copy"];
|
commands = ["cut", "paste", "copy"];
|
||||||
for (i = 0; i < commands.length; i++) {
|
for (i = 0; i < commands.length; i++) {
|
||||||
IsCommandEnabled(commands[i], commands[i] == "copy");
|
IsCommandEnabled(commands[i]);
|
||||||
document.execCommand(commands[i], false, false);
|
document.execCommand(commands[i], false, false);
|
||||||
}
|
}
|
||||||
SpecialPowers.clearUserPref("capability.policy.policynames");
|
SpecialPowers.clearUserPref("capability.policy.policynames");
|
||||||
|
@ -97,7 +108,7 @@ function runTests() {
|
||||||
// * there's nothing to redo if we haven't undone something first
|
// * there's nothing to redo if we haven't undone something first
|
||||||
commands = ["delete", "undo", "redo"];
|
commands = ["delete", "undo", "redo"];
|
||||||
for (i = 0; i < commands.length; i++) {
|
for (i = 0; i < commands.length; i++) {
|
||||||
IsCommandEnabled(commands[i], false);
|
IsCommandEnabled(commands[i]);
|
||||||
document.execCommand(commands[i], false, false);
|
document.execCommand(commands[i], false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,7 @@ NS_IMETHODIMP nsAppStartupNotifier::Observe(nsISupports *aSubject, const char *a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#ifdef NS_DEBUG
|
#ifdef DEBUG
|
||||||
nsCAutoString warnStr("Cannot create startup observer : ");
|
nsCAutoString warnStr("Cannot create startup observer : ");
|
||||||
warnStr += contractId.get();
|
warnStr += contractId.get();
|
||||||
NS_WARNING(warnStr.get());
|
NS_WARNING(warnStr.get());
|
||||||
|
|
|
@ -874,9 +874,9 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
|
||||||
IDWriteRenderingParams *params = NULL;
|
IDWriteRenderingParams *params = NULL;
|
||||||
if (aRenderOptions) {
|
if (aRenderOptions) {
|
||||||
if (aRenderOptions->GetType() != FONT_DWRITE) {
|
if (aRenderOptions->GetType() != FONT_DWRITE) {
|
||||||
gfxDebug() << *this << ": Ignoring incompatible GlyphRenderingOptions.";
|
gfxDebug() << *this << ": Ignoring incompatible GlyphRenderingOptions.";
|
||||||
// This should never happen.
|
// This should never happen.
|
||||||
MOZ_ASSERT(false);
|
MOZ_ASSERT(false);
|
||||||
} else {
|
} else {
|
||||||
params = static_cast<const GlyphRenderingOptionsDWrite*>(aRenderOptions)->mParams;
|
params = static_cast<const GlyphRenderingOptionsDWrite*>(aRenderOptions)->mParams;
|
||||||
}
|
}
|
||||||
|
@ -895,7 +895,12 @@ DrawTargetD2D::FillGlyphs(ScaledFont *aFont,
|
||||||
|
|
||||||
PrepareForDrawing(rt);
|
PrepareForDrawing(rt);
|
||||||
|
|
||||||
rt->SetTextRenderingParams(params);
|
if (rt != mRT || params != mTextRenderingParams) {
|
||||||
|
rt->SetTextRenderingParams(params);
|
||||||
|
if (rt == mRT) {
|
||||||
|
mTextRenderingParams = params;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
RefPtr<ID2D1Brush> brush = CreateBrushForPattern(aPattern, aOptions.mAlpha);
|
||||||
|
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче