зеркало из https://github.com/mozilla/pjs.git
Merge last green changeset from mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
7bd1e6eb70
|
@ -111,97 +111,53 @@ getActionNameCB(AtkAction *aAction, gint aActionIndex)
|
|||
const gchar *
|
||||
getKeyBindingCB(AtkAction *aAction, gint aActionIndex)
|
||||
{
|
||||
nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aAction));
|
||||
if (!accWrap)
|
||||
return nsnull;
|
||||
nsAccessibleWrap* acc = GetAccessibleWrap(ATK_OBJECT(aAction));
|
||||
if (!acc)
|
||||
return nsnull;
|
||||
|
||||
//return all KeyBindings including accesskey and shortcut
|
||||
nsAutoString allKeyBinding;
|
||||
// Return all key bindings including access key and keyboard shortcut.
|
||||
nsAutoString keyBindingsStr;
|
||||
|
||||
//get accesskey
|
||||
nsAutoString accessKey;
|
||||
nsresult rv = accWrap->GetKeyboardShortcut(accessKey);
|
||||
// Get access key.
|
||||
KeyBinding keyBinding = acc->AccessKey();
|
||||
if (!keyBinding.IsEmpty()) {
|
||||
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !accessKey.IsEmpty()) {
|
||||
nsAccessible* parent = accWrap->GetParent();
|
||||
if (parent) {
|
||||
PRUint32 atkRole = atkRoleMap[parent->NativeRole()];
|
||||
nsAccessible* parent = acc->GetParent();
|
||||
PRUint32 role = parent ? parent->Role() : 0;
|
||||
if (role == nsIAccessibleRole::ROLE_PARENT_MENUITEM ||
|
||||
role == nsIAccessibleRole::ROLE_MENUITEM ||
|
||||
role == nsIAccessibleRole::ROLE_RADIO_MENU_ITEM ||
|
||||
role == nsIAccessibleRole::ROLE_CHECK_MENU_ITEM) {
|
||||
// It is submenu, expose keyboard shortcuts from menu hierarchy like
|
||||
// "s;<Alt>f:s"
|
||||
nsAutoString keysInHierarchyStr = keyBindingsStr;
|
||||
do {
|
||||
KeyBinding parentKeyBinding = parent->AccessKey();
|
||||
if (!parentKeyBinding.IsEmpty()) {
|
||||
nsAutoString str;
|
||||
parentKeyBinding.ToString(str, KeyBinding::eAtkFormat);
|
||||
str.Append(':');
|
||||
|
||||
if (atkRole == ATK_ROLE_MENU_BAR) {
|
||||
//it is topmenu, change from "Alt+f" to "f;<Alt>f"
|
||||
nsAutoString rightChar;
|
||||
accessKey.Right(rightChar, 1);
|
||||
allKeyBinding = rightChar + NS_LITERAL_STRING(";<Alt>") +
|
||||
rightChar;
|
||||
}
|
||||
else if ((atkRole == ATK_ROLE_MENU) || (atkRole == ATK_ROLE_MENU_ITEM)) {
|
||||
//it is submenu, change from "s" to "s;<Alt>f:s"
|
||||
nsAutoString allKey = accessKey;
|
||||
nsAccessible* grandParent = parent;
|
||||
|
||||
do {
|
||||
nsAutoString grandParentKey;
|
||||
grandParent->GetKeyboardShortcut(grandParentKey);
|
||||
|
||||
if (!grandParentKey.IsEmpty()) {
|
||||
nsAutoString rightChar;
|
||||
grandParentKey.Right(rightChar, 1);
|
||||
allKey = rightChar + NS_LITERAL_STRING(":") + allKey;
|
||||
}
|
||||
|
||||
} while ((grandParent = grandParent->GetParent()) &&
|
||||
atkRoleMap[grandParent->NativeRole()] != ATK_ROLE_MENU_BAR);
|
||||
|
||||
allKeyBinding = accessKey + NS_LITERAL_STRING(";<Alt>") +
|
||||
allKey;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//default process, rarely happens.
|
||||
nsAutoString rightChar;
|
||||
accessKey.Right(rightChar, 1);
|
||||
allKeyBinding = rightChar + NS_LITERAL_STRING(";<Alt>") + rightChar;
|
||||
keysInHierarchyStr.Insert(str, 0);
|
||||
}
|
||||
} while ((parent = parent->GetParent()) &&
|
||||
parent->Role() != nsIAccessibleRole::ROLE_MENUBAR);
|
||||
|
||||
keyBindingsStr.Append(';');
|
||||
keyBindingsStr.Append(keysInHierarchyStr);
|
||||
}
|
||||
else //don't have accesskey
|
||||
allKeyBinding.AssignLiteral(";");
|
||||
} else {
|
||||
// No access key, add ';' to point this.
|
||||
keyBindingsStr.Append(';');
|
||||
}
|
||||
|
||||
//get shortcut
|
||||
nsAutoString subShortcut;
|
||||
nsCOMPtr<nsIDOMDOMStringList> keyBindings;
|
||||
rv = accWrap->GetKeyBindings(aActionIndex, getter_AddRefs(keyBindings));
|
||||
// Get keyboard shortcut.
|
||||
keyBindingsStr.Append(';');
|
||||
keyBinding = acc->KeyboardShortcut();
|
||||
if (!keyBinding.IsEmpty()) {
|
||||
keyBinding.AppendToString(keyBindingsStr, KeyBinding::eAtkFormat);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && keyBindings) {
|
||||
PRUint32 length = 0;
|
||||
keyBindings->GetLength(&length);
|
||||
for (PRUint32 i = 0; i < length; i++) {
|
||||
nsAutoString keyBinding;
|
||||
keyBindings->Item(i, keyBinding);
|
||||
|
||||
//change the shortcut from "Ctrl+Shift+L" to "<Control><Shift>L"
|
||||
PRInt32 oldPos, curPos=0;
|
||||
while ((curPos != -1) && (curPos < (PRInt32)keyBinding.Length())) {
|
||||
oldPos = curPos;
|
||||
nsAutoString subString;
|
||||
curPos = keyBinding.FindChar('+', oldPos);
|
||||
if (curPos == -1) {
|
||||
keyBinding.Mid(subString, oldPos, keyBinding.Length() - oldPos);
|
||||
subShortcut += subString;
|
||||
} else {
|
||||
keyBinding.Mid(subString, oldPos, curPos - oldPos);
|
||||
|
||||
//change "Ctrl" to "Control"
|
||||
if (subString.LowerCaseEqualsLiteral("ctrl"))
|
||||
subString.AssignLiteral("Control");
|
||||
|
||||
subShortcut += NS_LITERAL_STRING("<") + subString +
|
||||
NS_LITERAL_STRING(">");
|
||||
curPos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allKeyBinding += NS_LITERAL_STRING(";") + subShortcut;
|
||||
return nsAccessibleWrap::ReturnString(allKeyBinding);
|
||||
return nsAccessibleWrap::ReturnString(keyBindingsStr);
|
||||
}
|
||||
|
|
|
@ -258,17 +258,9 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
if (ownerContent) {
|
||||
nsAccessible* outerDocAcc = mDocument->GetAccessible(ownerContent);
|
||||
if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
|
||||
if (mDocument->AppendChildDocument(childDoc)) {
|
||||
// Fire reorder event to notify new accessible document has been
|
||||
// attached to the tree.
|
||||
nsRefPtr<AccEvent> reorderEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, outerDocAcc,
|
||||
eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
|
||||
if (reorderEvent)
|
||||
QueueEvent(reorderEvent);
|
||||
|
||||
if (mDocument->AppendChildDocument(childDoc))
|
||||
continue;
|
||||
}
|
||||
|
||||
outerDocAcc->RemoveChild(childDoc);
|
||||
}
|
||||
|
||||
|
|
|
@ -468,12 +468,13 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
|
|||
}
|
||||
|
||||
// Fire reorder event to notify new accessible document has been attached to
|
||||
// the tree.
|
||||
// the tree. The reorder event is delivered after the document tree is
|
||||
// constructed because event processing and tree construction are done by
|
||||
// the same document.
|
||||
nsRefPtr<AccEvent> reorderEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, appAcc, eAutoDetect,
|
||||
AccEvent::eCoalesceFromSameSubtree);
|
||||
if (reorderEvent)
|
||||
docAcc->FireDelayedAccessibleEvent(reorderEvent);
|
||||
docAcc->FireDelayedAccessibleEvent(reorderEvent);
|
||||
|
||||
} else {
|
||||
parentDocAcc->BindChildDocument(docAcc);
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
*/
|
||||
|
||||
nsIStringBundle *nsAccessNode::gStringBundle = 0;
|
||||
nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
|
||||
nsINode *nsAccessNode::gLastFocusedNode = nsnull;
|
||||
|
||||
PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
|
||||
|
@ -210,8 +209,6 @@ void nsAccessNode::InitXPAccessibility()
|
|||
// Static variables are released in ShutdownAllXPAccessibility();
|
||||
stringBundleService->CreateBundle(ACCESSIBLE_BUNDLE_URL,
|
||||
&gStringBundle);
|
||||
stringBundleService->CreateBundle(PLATFORM_KEYS_BUNDLE_URL,
|
||||
&gKeyStringBundle);
|
||||
}
|
||||
|
||||
nsAccessibilityAtoms::AddRefAtoms();
|
||||
|
@ -246,7 +243,6 @@ void nsAccessNode::ShutdownXPAccessibility()
|
|||
// at exit of program
|
||||
|
||||
NS_IF_RELEASE(gStringBundle);
|
||||
NS_IF_RELEASE(gKeyStringBundle);
|
||||
NS_IF_RELEASE(gLastFocusedNode);
|
||||
|
||||
// Release gApplicationAccessible after everything else is shutdown
|
||||
|
|
|
@ -215,7 +215,6 @@ protected:
|
|||
|
||||
// Static data, we do our own refcounting for our static data
|
||||
static nsIStringBundle *gStringBundle;
|
||||
static nsIStringBundle *gKeyStringBundle;
|
||||
|
||||
static PRBool gIsFormFillEnabled;
|
||||
|
||||
|
|
|
@ -329,55 +329,6 @@ nsAccessible::Description(nsString& aDescription)
|
|||
aDescription.CompressWhitespace();
|
||||
}
|
||||
|
||||
// mask values for ui.key.chromeAccess and ui.key.contentAccess
|
||||
#define NS_MODIFIER_SHIFT 1
|
||||
#define NS_MODIFIER_CONTROL 2
|
||||
#define NS_MODIFIER_ALT 4
|
||||
#define NS_MODIFIER_META 8
|
||||
|
||||
// returns the accesskey modifier mask used in the given node's context
|
||||
// (i.e. chrome or content), or 0 if an error occurs
|
||||
static PRInt32
|
||||
GetAccessModifierMask(nsIContent* aContent)
|
||||
{
|
||||
// use ui.key.generalAccessKey (unless it is -1)
|
||||
switch (Preferences::GetInt("ui.key.generalAccessKey", -1)) {
|
||||
case -1: break;
|
||||
case nsIDOMKeyEvent::DOM_VK_SHIFT: return NS_MODIFIER_SHIFT;
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL: return NS_MODIFIER_CONTROL;
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT: return NS_MODIFIER_ALT;
|
||||
case nsIDOMKeyEvent::DOM_VK_META: return NS_MODIFIER_META;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
// get the docShell to this DOMNode, return 0 on failure
|
||||
nsCOMPtr<nsIDocument> document = aContent->GetCurrentDoc();
|
||||
if (!document)
|
||||
return 0;
|
||||
nsCOMPtr<nsISupports> container = document->GetContainer();
|
||||
if (!container)
|
||||
return 0;
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
|
||||
if (!treeItem)
|
||||
return 0;
|
||||
|
||||
// determine the access modifier used in this context
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
PRInt32 itemType, accessModifierMask = 0;
|
||||
treeItem->GetItemType(&itemType);
|
||||
switch (itemType) {
|
||||
case nsIDocShellTreeItem::typeChrome:
|
||||
rv = Preferences::GetInt("ui.key.chromeAccess", &accessModifierMask);
|
||||
break;
|
||||
|
||||
case nsIDocShellTreeItem::typeContent:
|
||||
rv = Preferences::GetInt("ui.key.contentAccess", &accessModifierMask);
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(rv) ? accessModifierMask : 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
||||
{
|
||||
|
@ -386,6 +337,13 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
|||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
AccessKey().ToString(aAccessKey);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
KeyBinding
|
||||
nsAccessible::AccessKey() const
|
||||
{
|
||||
PRUint32 key = nsCoreUtils::GetAccessKeyFor(mContent);
|
||||
if (!key && mContent->IsElement()) {
|
||||
nsAccessible* label = nsnull;
|
||||
|
@ -408,32 +366,54 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
|||
}
|
||||
|
||||
if (!key)
|
||||
return NS_OK;
|
||||
return KeyBinding();
|
||||
|
||||
nsAutoString accesskey(key);
|
||||
|
||||
// Append the modifiers in reverse order, result: Control+Alt+Shift+Meta+<key>
|
||||
nsAutoString propertyKey;
|
||||
PRInt32 modifierMask = GetAccessModifierMask(mContent);
|
||||
if (modifierMask & NS_MODIFIER_META) {
|
||||
propertyKey.AssignLiteral("VK_META");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_SHIFT) {
|
||||
propertyKey.AssignLiteral("VK_SHIFT");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_ALT) {
|
||||
propertyKey.AssignLiteral("VK_ALT");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
}
|
||||
if (modifierMask & NS_MODIFIER_CONTROL) {
|
||||
propertyKey.AssignLiteral("VK_CONTROL");
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, accesskey);
|
||||
// Get modifier mask. Use ui.key.generalAccessKey (unless it is -1).
|
||||
switch (Preferences::GetInt("ui.key.generalAccessKey", -1)) {
|
||||
case -1:
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_SHIFT:
|
||||
return KeyBinding(key, KeyBinding::kShift);
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
return KeyBinding(key, KeyBinding::kControl);
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
return KeyBinding(key, KeyBinding::kAlt);
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
return KeyBinding(key, KeyBinding::kMeta);
|
||||
default:
|
||||
return KeyBinding();
|
||||
}
|
||||
|
||||
aAccessKey = accesskey;
|
||||
return NS_OK;
|
||||
// Determine the access modifier used in this context.
|
||||
nsIDocument* document = mContent->GetCurrentDoc();
|
||||
if (!document)
|
||||
return KeyBinding();
|
||||
nsCOMPtr<nsISupports> container = document->GetContainer();
|
||||
if (!container)
|
||||
return KeyBinding();
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
|
||||
if (!treeItem)
|
||||
return KeyBinding();
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
PRInt32 itemType = 0, modifierMask = 0;
|
||||
treeItem->GetItemType(&itemType);
|
||||
switch (itemType) {
|
||||
case nsIDocShellTreeItem::typeChrome:
|
||||
rv = Preferences::GetInt("ui.key.chromeAccess", &modifierMask);
|
||||
break;
|
||||
case nsIDocShellTreeItem::typeContent:
|
||||
rv = Preferences::GetInt("ui.key.contentAccess", &modifierMask);
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(rv) ? KeyBinding(key, modifierMask) : KeyBinding();
|
||||
}
|
||||
|
||||
KeyBinding
|
||||
nsAccessible::KeyboardShortcut() const
|
||||
{
|
||||
return KeyBinding();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -604,22 +584,6 @@ nsresult nsAccessible::GetTranslatedString(const nsAString& aKey, nsAString& aSt
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsAccessible::GetFullKeyName(const nsAString& aModifierName, const nsAString& aKeyName, nsAString& aStringOut)
|
||||
{
|
||||
nsXPIDLString modifierName, separator;
|
||||
|
||||
if (!gKeyStringBundle ||
|
||||
NS_FAILED(gKeyStringBundle->GetStringFromName(PromiseFlatString(aModifierName).get(),
|
||||
getter_Copies(modifierName))) ||
|
||||
NS_FAILED(gKeyStringBundle->GetStringFromName(NS_LITERAL_STRING("MODIFIER_SEPARATOR").get(),
|
||||
getter_Copies(separator)))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aStringOut = modifierName + separator + aKeyName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccessible::IsVisible(PRBool* aIsOffscreen)
|
||||
{
|
||||
|
@ -1788,6 +1752,10 @@ NS_IMETHODIMP
|
|||
nsAccessible::GetDefaultKeyBinding(nsAString& aKeyBinding)
|
||||
{
|
||||
aKeyBinding.Truncate();
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
KeyboardShortcut().ToString(aKeyBinding);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3359,3 +3327,79 @@ nsAccessible::GetLevelInternal()
|
|||
|
||||
return level;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// KeyBinding class
|
||||
|
||||
void
|
||||
KeyBinding::ToPlatformFormat(nsAString& aValue) const
|
||||
{
|
||||
nsCOMPtr<nsIStringBundle> keyStringBundle;
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
if (stringBundleService)
|
||||
stringBundleService->CreateBundle(PLATFORM_KEYS_BUNDLE_URL,
|
||||
getter_AddRefs(keyStringBundle));
|
||||
|
||||
if (!keyStringBundle)
|
||||
return;
|
||||
|
||||
nsAutoString separator;
|
||||
keyStringBundle->GetStringFromName(NS_LITERAL_STRING("MODIFIER_SEPARATOR").get(),
|
||||
getter_Copies(separator));
|
||||
|
||||
nsAutoString modifierName;
|
||||
if (mModifierMask & kControl) {
|
||||
keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_CONTROL").get(),
|
||||
getter_Copies(modifierName));
|
||||
|
||||
aValue.Append(modifierName);
|
||||
aValue.Append(separator);
|
||||
}
|
||||
|
||||
if (mModifierMask & kAlt) {
|
||||
keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_ALT").get(),
|
||||
getter_Copies(modifierName));
|
||||
|
||||
aValue.Append(modifierName);
|
||||
aValue.Append(separator);
|
||||
}
|
||||
|
||||
if (mModifierMask & kShift) {
|
||||
keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_SHIFT").get(),
|
||||
getter_Copies(modifierName));
|
||||
|
||||
aValue.Append(modifierName);
|
||||
aValue.Append(separator);
|
||||
}
|
||||
|
||||
if (mModifierMask & kMeta) {
|
||||
keyStringBundle->GetStringFromName(NS_LITERAL_STRING("VK_META").get(),
|
||||
getter_Copies(modifierName));
|
||||
|
||||
aValue.Append(modifierName);
|
||||
aValue.Append(separator);
|
||||
}
|
||||
|
||||
aValue.Append(mKey);
|
||||
}
|
||||
|
||||
void
|
||||
KeyBinding::ToAtkFormat(nsAString& aValue) const
|
||||
{
|
||||
nsAutoString modifierName;
|
||||
if (mModifierMask & kControl)
|
||||
aValue.Append(NS_LITERAL_STRING("<Control>"));
|
||||
|
||||
if (mModifierMask & kAlt)
|
||||
aValue.Append(NS_LITERAL_STRING("<Alt>"));
|
||||
|
||||
if (mModifierMask & kShift)
|
||||
aValue.Append(NS_LITERAL_STRING("<Shift>"));
|
||||
|
||||
if (mModifierMask & kMeta)
|
||||
aValue.Append(NS_LITERAL_STRING("<Meta>"));
|
||||
|
||||
aValue.Append(mKey);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
class AccEvent;
|
||||
class AccGroupInfo;
|
||||
class EmbeddedObjCollector;
|
||||
class KeyBinding;
|
||||
class nsAccessible;
|
||||
class nsHyperTextAccessible;
|
||||
class nsHTMLLIAccessible;
|
||||
|
@ -401,6 +402,20 @@ public:
|
|||
inline bool IsTextLeaf() const { return mFlags & eTextLeafAccessible; }
|
||||
nsTextAccessible* AsTextLeaf();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// ActionAccessible
|
||||
|
||||
/**
|
||||
* Return access key, such as Alt+D.
|
||||
*/
|
||||
virtual KeyBinding AccessKey() const;
|
||||
|
||||
/**
|
||||
* Return global keyboard shortcut for default action, such as Ctrl+O for
|
||||
* Open file menuitem.
|
||||
*/
|
||||
virtual KeyBinding KeyboardShortcut() const;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// HyperLinkAccessible
|
||||
|
||||
|
@ -692,4 +707,61 @@ protected:
|
|||
NS_DEFINE_STATIC_IID_ACCESSOR(nsAccessible,
|
||||
NS_ACCESSIBLE_IMPL_IID)
|
||||
|
||||
|
||||
/**
|
||||
* Represent key binding associated with accessible (such as access key and
|
||||
* global keyboard shortcuts).
|
||||
*/
|
||||
class KeyBinding
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Modifier mask values.
|
||||
*/
|
||||
static const PRUint32 kShift = 1;
|
||||
static const PRUint32 kControl = 2;
|
||||
static const PRUint32 kAlt = 4;
|
||||
static const PRUint32 kMeta = 8;
|
||||
|
||||
KeyBinding() : mKey(0), mModifierMask(0) {}
|
||||
KeyBinding(PRUint32 aKey, PRUint32 aModifierMask) :
|
||||
mKey(aKey), mModifierMask(aModifierMask) {};
|
||||
|
||||
inline bool IsEmpty() const { return !mKey; }
|
||||
inline PRUint32 Key() const { return mKey; }
|
||||
inline PRUint32 ModifierMask() const { return mModifierMask; }
|
||||
|
||||
enum Format {
|
||||
ePlatformFormat,
|
||||
eAtkFormat
|
||||
};
|
||||
|
||||
/**
|
||||
* Return formatted string for this key binding depending on the given format.
|
||||
*/
|
||||
inline void ToString(nsAString& aValue,
|
||||
Format aFormat = ePlatformFormat) const
|
||||
{
|
||||
aValue.Truncate();
|
||||
AppendToString(aValue, aFormat);
|
||||
}
|
||||
inline void AppendToString(nsAString& aValue,
|
||||
Format aFormat = ePlatformFormat) const
|
||||
{
|
||||
if (mKey) {
|
||||
if (aFormat == ePlatformFormat)
|
||||
ToPlatformFormat(aValue);
|
||||
else
|
||||
ToAtkFormat(aValue);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void ToPlatformFormat(nsAString& aValue) const;
|
||||
void ToAtkFormat(nsAString& aValue) const;
|
||||
|
||||
PRUint32 mKey;
|
||||
PRUint32 mModifierMask;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -133,13 +133,6 @@ nsApplicationAccessible::Description(nsString &aDescription)
|
|||
aDescription.Truncate();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetKeyboardShortcut(nsAString &aKeyboardShortcut)
|
||||
{
|
||||
aKeyboardShortcut.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsApplicationAccessible::State()
|
||||
{
|
||||
|
|
|
@ -91,7 +91,6 @@ public:
|
|||
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
|
||||
NS_IMETHOD GetName(nsAString &aName);
|
||||
NS_IMETHOD GetValue(nsAString &aValue);
|
||||
NS_IMETHOD GetKeyboardShortcut(nsAString &aKeyboardShortcut);
|
||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||
NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
|
||||
PRInt32 *aPositionInGroup);
|
||||
|
|
|
@ -175,13 +175,11 @@ nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
|||
nsAccessibleWrap::DoAction(aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
KeyBinding
|
||||
nsLinkableAccessible::AccessKey() const
|
||||
{
|
||||
aKeyboardShortcut.Truncate();
|
||||
|
||||
return mActionAcc ? mActionAcc->GetKeyboardShortcut(aKeyboardShortcut) :
|
||||
nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
|
||||
return mActionAcc ?
|
||||
mActionAcc->AccessKey() : nsAccessible::AccessKey();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -92,7 +92,6 @@ public:
|
|||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
NS_IMETHOD GetValue(nsAString& _retval);
|
||||
NS_IMETHOD TakeFocus();
|
||||
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
||||
|
||||
// nsAccessNode
|
||||
virtual void Shutdown();
|
||||
|
@ -100,6 +99,9 @@ public:
|
|||
// nsAccessible
|
||||
virtual PRUint64 NativeState();
|
||||
|
||||
// ActionAccessible
|
||||
virtual KeyBinding AccessKey() const;
|
||||
|
||||
// HyperLinkAccessible
|
||||
virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
|
||||
|
||||
|
|
|
@ -1494,6 +1494,17 @@ nsDocAccessible::NotifyOfInitialUpdate()
|
|||
|
||||
// Build initial tree.
|
||||
CacheChildrenInSubtree(this);
|
||||
|
||||
// Fire reorder event after the document tree is constructed. Note, since
|
||||
// this reorder event is processed by parent document then events targeted to
|
||||
// this document may be fired prior to this reorder event. If this is
|
||||
// a problem then consider to keep event processing per tab document.
|
||||
if (!IsRoot()) {
|
||||
nsRefPtr<AccEvent> reorderEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, GetParent(),
|
||||
eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
|
||||
ParentDocument()->FireDelayedAccessibleEvent(reorderEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -42,11 +42,7 @@
|
|||
|
||||
#include "AccessibleAction_i.c"
|
||||
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsAccessNodeWrap.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIDOMDOMStringList.h"
|
||||
#include "nsAccessible.h"
|
||||
|
||||
// IUnknown
|
||||
|
||||
|
@ -137,54 +133,44 @@ CAccessibleAction::get_keyBinding(long aActionIndex, long aNumMaxBinding,
|
|||
long *aNumBinding)
|
||||
{
|
||||
__try {
|
||||
if (!aKeyBinding)
|
||||
return E_INVALIDARG;
|
||||
*aKeyBinding = NULL;
|
||||
|
||||
if (!aNumBinding)
|
||||
return E_INVALIDARG;
|
||||
*aNumBinding = 0;
|
||||
|
||||
nsCOMPtr<nsIAccessible> acc(do_QueryObject(this));
|
||||
if (!acc)
|
||||
if (aActionIndex != 0 || aNumMaxBinding < 1)
|
||||
return E_INVALIDARG;
|
||||
|
||||
nsRefPtr<nsAccessible> acc(do_QueryObject(this));
|
||||
if (!acc || acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIDOMDOMStringList> keys;
|
||||
PRUint8 index = static_cast<PRUint8>(aActionIndex);
|
||||
nsresult rv = acc->GetKeyBindings(index, getter_AddRefs(keys));
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
PRUint32 length = 0;
|
||||
keys->GetLength(&length);
|
||||
if (length == 0)
|
||||
// Expose keyboard shortcut if it's not exposed via MSAA keyboard shortcut.
|
||||
KeyBinding keyBinding = acc->AccessKey();
|
||||
if (keyBinding.IsEmpty())
|
||||
return S_FALSE;
|
||||
|
||||
PRUint32 maxBinding = static_cast<PRUint32>(aNumMaxBinding);
|
||||
PRUint32 numBinding = length > maxBinding ? maxBinding : length;
|
||||
*aNumBinding = numBinding;
|
||||
keyBinding = acc->KeyboardShortcut();
|
||||
if (keyBinding.IsEmpty())
|
||||
return S_FALSE;
|
||||
|
||||
*aKeyBinding = static_cast<BSTR*>(nsMemory::Alloc((numBinding) * sizeof(BSTR*)));
|
||||
nsAutoString keyStr;
|
||||
keyBinding.ToString(keyStr);
|
||||
|
||||
*aKeyBinding = static_cast<BSTR*>(::CoTaskMemAlloc(sizeof(BSTR*)));
|
||||
if (!*aKeyBinding)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
PRBool outOfMemory = PR_FALSE;
|
||||
PRUint32 i = 0;
|
||||
for (; i < numBinding; i++) {
|
||||
nsAutoString key;
|
||||
keys->Item(i, key);
|
||||
*(aKeyBinding[i]) = ::SysAllocStringLen(key.get(), key.Length());
|
||||
|
||||
if (!*(aKeyBinding[i])) {
|
||||
outOfMemory = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (outOfMemory) {
|
||||
for (PRUint32 j = 0; j < i; j++)
|
||||
::SysFreeString(*(aKeyBinding[j]));
|
||||
|
||||
nsMemory::Free(*aKeyBinding);
|
||||
*aKeyBinding = NULL;
|
||||
|
||||
*(aKeyBinding[0]) = ::SysAllocStringLen(keyStr.get(), keyStr.Length());
|
||||
if (!*(aKeyBinding[0])) {
|
||||
::CoTaskMemFree(*aKeyBinding);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
*aNumBinding = 1;
|
||||
return S_OK;
|
||||
|
||||
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
|
||||
|
|
|
@ -486,16 +486,18 @@ STDMETHODIMP nsAccessibleWrap::get_accKeyboardShortcut(
|
|||
__try {
|
||||
if (!pszKeyboardShortcut)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*pszKeyboardShortcut = NULL;
|
||||
nsAccessible *xpAccessible = GetXPAccessibleFor(varChild);
|
||||
if (!xpAccessible || xpAccessible->IsDefunct())
|
||||
|
||||
nsAccessible* acc = GetXPAccessibleFor(varChild);
|
||||
if (!acc || acc->IsDefunct())
|
||||
return E_FAIL;
|
||||
|
||||
KeyBinding keyBinding = acc->AccessKey();
|
||||
if (keyBinding.IsEmpty())
|
||||
keyBinding = acc->KeyboardShortcut();
|
||||
|
||||
nsAutoString shortcut;
|
||||
nsresult rv = xpAccessible->GetKeyboardShortcut(shortcut);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
keyBinding.ToString(shortcut);
|
||||
|
||||
*pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(),
|
||||
shortcut.Length());
|
||||
|
|
|
@ -387,14 +387,10 @@ nsXULMenuitemAccessible::Description(nsString& aDescription)
|
|||
aDescription);
|
||||
}
|
||||
|
||||
//return menu accesskey: N or Alt+F
|
||||
NS_IMETHODIMP
|
||||
nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
||||
KeyBinding
|
||||
nsXULMenuitemAccessible::AccessKey() const
|
||||
{
|
||||
aAccessKey.Truncate();
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Return menu accesskey: N or Alt+F.
|
||||
static PRInt32 gMenuAccesskeyModifier = -1; // magic value of -1 indicates unitialized state
|
||||
|
||||
// We do not use nsCoreUtils::GetAccesskeyFor() because accesskeys for
|
||||
|
@ -403,7 +399,9 @@ nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
|||
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::accesskey,
|
||||
accesskey);
|
||||
if (accesskey.IsEmpty())
|
||||
return NS_OK;
|
||||
return KeyBinding();
|
||||
|
||||
PRUint32 modifierKey = 0;
|
||||
|
||||
nsAccessible* parentAcc = GetParent();
|
||||
if (parentAcc) {
|
||||
|
@ -415,44 +413,89 @@ nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
|||
gMenuAccesskeyModifier = Preferences::GetInt("ui.key.menuAccessKey", 0);
|
||||
}
|
||||
|
||||
nsAutoString propertyKey;
|
||||
switch (gMenuAccesskeyModifier) {
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
propertyKey.AssignLiteral("VK_CONTROL");
|
||||
modifierKey = KeyBinding::kControl;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
propertyKey.AssignLiteral("VK_ALT");
|
||||
modifierKey = KeyBinding::kAlt;
|
||||
break;
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
propertyKey.AssignLiteral("VK_META");
|
||||
modifierKey = KeyBinding::kMeta;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!propertyKey.IsEmpty())
|
||||
nsAccessible::GetFullKeyName(propertyKey, accesskey, aAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (aAccessKey.IsEmpty())
|
||||
aAccessKey = accesskey;
|
||||
|
||||
return NS_OK;
|
||||
return KeyBinding(accesskey[0], modifierKey);
|
||||
}
|
||||
|
||||
//return menu shortcut: Ctrl+F or Ctrl+Shift+L
|
||||
NS_IMETHODIMP
|
||||
nsXULMenuitemAccessible::GetDefaultKeyBinding(nsAString& aKeyBinding)
|
||||
KeyBinding
|
||||
nsXULMenuitemAccessible::KeyboardShortcut() const
|
||||
{
|
||||
aKeyBinding.Truncate();
|
||||
nsAutoString keyElmId;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyElmId);
|
||||
if (keyElmId.IsEmpty())
|
||||
return KeyBinding();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
nsIDocument* document = mContent->GetOwnerDoc();
|
||||
if (!document)
|
||||
return KeyBinding();
|
||||
|
||||
nsAutoString accelText;
|
||||
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::acceltext,
|
||||
aKeyBinding);
|
||||
nsIContent* keyElm = document->GetElementById(keyElmId);
|
||||
if (!keyElm)
|
||||
return KeyBinding();
|
||||
|
||||
return NS_OK;
|
||||
PRUint32 key = 0;
|
||||
|
||||
nsAutoString keyStr;
|
||||
keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::key, keyStr);
|
||||
if (keyStr.IsEmpty()) {
|
||||
nsAutoString keyCodeStr;
|
||||
keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::keycode, keyCodeStr);
|
||||
PRUint32 errorCode;
|
||||
key = keyStr.ToInteger(&errorCode, kAutoDetect);
|
||||
} else {
|
||||
key = keyStr[0];
|
||||
}
|
||||
|
||||
nsAutoString modifiersStr;
|
||||
keyElm->GetAttr(kNameSpaceID_None, nsGkAtoms::modifiers, modifiersStr);
|
||||
|
||||
PRUint32 modifierMask = 0;
|
||||
if (modifiersStr.Find("shift") != -1)
|
||||
modifierMask != KeyBinding::kShift;
|
||||
if (modifiersStr.Find("alt") != -1)
|
||||
modifierMask |= KeyBinding::kAlt;
|
||||
if (modifiersStr.Find("meta") != -1)
|
||||
modifierMask |= KeyBinding::kMeta;
|
||||
if (modifiersStr.Find("control") != -1)
|
||||
modifierMask |= KeyBinding::kControl;
|
||||
if (modifiersStr.Find("accel") != -1) {
|
||||
// Get the accelerator key value from prefs, overriding the default.
|
||||
switch (Preferences::GetInt("ui.key.accelKey", 0)) {
|
||||
case nsIDOMKeyEvent::DOM_VK_META:
|
||||
modifierMask |= KeyBinding::kMeta;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT:
|
||||
modifierMask |= KeyBinding::kAlt;
|
||||
break;
|
||||
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL:
|
||||
modifierMask |= KeyBinding::kControl;
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef XP_MACOSX
|
||||
modifierMask |= KeyBinding::kMeta;
|
||||
#else
|
||||
modifierMask |= KeyBinding::kControl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return KeyBinding(key, modifierMask);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
|
|
@ -82,8 +82,6 @@ public:
|
|||
nsXULMenuitemAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
||||
NS_IMETHOD GetDefaultKeyBinding(nsAString& aKeyBinding);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||
|
@ -98,6 +96,10 @@ public:
|
|||
PRInt32 *aSetSize);
|
||||
|
||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||
|
||||
// ActionAccessible
|
||||
virtual KeyBinding AccessKey() const;
|
||||
virtual KeyBinding KeyboardShortcut() const;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -97,7 +97,6 @@ _TEST_FILES =\
|
|||
test_elm_listbox.xul \
|
||||
test_elm_nsApplicationAcc.html \
|
||||
test_elm_plugin.html \
|
||||
test_keys.html \
|
||||
test_nsIAccessible_selects.html \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
|
|
|
@ -51,6 +51,8 @@ _TEST_FILES =\
|
|||
test_general.html \
|
||||
test_general.xul \
|
||||
test_inputs.html \
|
||||
test_keys_menu.xul \
|
||||
test_keys.html \
|
||||
test_link.html \
|
||||
test_media.html \
|
||||
test_tree.xul \
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="common.js"></script>
|
||||
src="../common.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function testKeyboardShortcut(aAccOrElmOrID, aKey)
|
||||
|
@ -29,6 +29,7 @@
|
|||
{
|
||||
testKeyboardShortcut("input1", "");
|
||||
testKeyboardShortcut("input2", MAC ? "⌃b" : "Alt+Shift+b");
|
||||
testKeyboardShortcut("link", MAC ? "⌃l" : "Alt+Shift+l");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -56,5 +57,6 @@
|
|||
</label>
|
||||
<label accesskey="b" for="input2">
|
||||
<input id="input2"/>
|
||||
<a id="link" accesskey="l">link</a>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessible XUL access keys and shortcut keys tests">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function openMenu(aMenuID, aMenuitemID)
|
||||
{
|
||||
this.menuNode = getNode(aMenuID),
|
||||
this.menuitemNode = getNode(aMenuitemID),
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, this.menuNode)
|
||||
];
|
||||
|
||||
this.invoke = function openMenu_invoke()
|
||||
{
|
||||
// Show menu.
|
||||
this.menuNode.open = true;
|
||||
}
|
||||
|
||||
this.finalCheck = function openMenu_finalCheck()
|
||||
{
|
||||
var menu = getAccessible(aMenuID);
|
||||
is(menu.keyboardShortcut, (MAC ? "u" : "Alt+u"),
|
||||
"Wrong accesskey on " + prettyName(this.menuitemNode));
|
||||
|
||||
var menuitem = getAccessible(aMenuitemID);
|
||||
is(menuitem.keyboardShortcut, "p",
|
||||
"Wrong accesskey on " + prettyName(this.menuitemNode));
|
||||
is(menuitem.defaultKeyBinding, (MAC ? "⌃l" : "Ctrl+l"),
|
||||
"Wrong keyboard shortcut on " + prettyName(this.menuitemNode));
|
||||
}
|
||||
|
||||
this.getID = function openMenu_getID()
|
||||
{
|
||||
return "menuitem accesskey and shortcut test " +
|
||||
prettyName(this.menuItemNode);
|
||||
}
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new openMenu("menu", "menuitem"));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=672092"
|
||||
title="Reorganize access key and keyboard shortcut handling code">
|
||||
Mozilla Bug 672092
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<keyset>
|
||||
<key key="l" modifiers="control" id="key1"/>
|
||||
</keyset>
|
||||
|
||||
<menubar>
|
||||
<menu label="menu" id="menu" accesskey="u">
|
||||
<menupopup>
|
||||
<menuitem accesskey="p" key="key1" label="item1" id="menuitem"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
<vbox id="debug"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
@ -159,11 +159,23 @@ const DO_NOT_FINISH_TEST = 1;
|
|||
* // Checker object interface:
|
||||
* //
|
||||
* // var checker = {
|
||||
* // type getter: function() {}, // DOM or a11y event type
|
||||
* // target getter: function() {}, // DOM node or accessible
|
||||
* // phase getter: function() {}, // DOM event phase (false - bubbling)
|
||||
* // * DOM or a11y event type. *
|
||||
* // type getter: function() {},
|
||||
* //
|
||||
* // * DOM node or accessible. *
|
||||
* // target getter: function() {},
|
||||
* //
|
||||
* // * DOM event phase (false - bubbling). *
|
||||
* // phase getter: function() {},
|
||||
* //
|
||||
* // * Callback, called when event is handled
|
||||
* // check: function(aEvent) {},
|
||||
* // getID: function() {}
|
||||
* //
|
||||
* // * Checker ID *
|
||||
* // getID: function() {},
|
||||
* //
|
||||
* // * Event that don't have predefined order relative other events. *
|
||||
* // async getter: function() {}
|
||||
* // };
|
||||
* eventSeq getter() {},
|
||||
*
|
||||
|
@ -327,10 +339,11 @@ function eventQueue(aEventType)
|
|||
if ("debugCheck" in invoker)
|
||||
invoker.debugCheck(aEvent);
|
||||
|
||||
// Search through handled expected events if one of them was handled again.
|
||||
// Search through handled expected events to report error if one of them is
|
||||
// handled for a second time.
|
||||
var idx = 0;
|
||||
for (; idx < this.mEventSeq.length; idx++) {
|
||||
if (!this.isEventUnexpected(idx) && (invoker.wasCaught[idx] == true) &&
|
||||
if (this.isEventExpected(idx) && (invoker.wasCaught[idx] == true) &&
|
||||
this.isAlreadyCaught(idx, aEvent)) {
|
||||
|
||||
var msg = "Doubled event { event type: " +
|
||||
|
@ -341,52 +354,85 @@ function eventQueue(aEventType)
|
|||
}
|
||||
}
|
||||
|
||||
// Search through unexpected events to ensure no one of them was handled.
|
||||
// Search through unexpected events, any matches result in error report
|
||||
// after this invoker processing.
|
||||
for (idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
if (this.isEventUnexpected(idx) && this.compareEvents(idx, aEvent))
|
||||
invoker.wasCaught[idx] = true;
|
||||
}
|
||||
|
||||
// We've handled all expected events, next invoker processing is pending.
|
||||
if (this.mEventSeqIdx == this.mEventSeq.length)
|
||||
// Nothing left, proceed next invoker in timeout. Otherwise check if
|
||||
// handled event is matched.
|
||||
var idxObj = {};
|
||||
if (!this.prepareForExpectedEvent(invoker, idxObj))
|
||||
return;
|
||||
|
||||
// Compute next expected event index.
|
||||
for (idx = this.mEventSeqIdx + 1;
|
||||
idx < this.mEventSeq.length && this.mEventSeq[idx].unexpected;
|
||||
idx++);
|
||||
|
||||
// No expected events were registered, proceed to next invoker to ensure
|
||||
// unexpected events for current invoker won't be handled.
|
||||
if (idx == this.mEventSeq.length) {
|
||||
this.mEventSeqIdx = idx;
|
||||
this.processNextInvokerInTimeout();
|
||||
return;
|
||||
// Check if handled event matches expected sync event.
|
||||
var matched = false;
|
||||
idx = idxObj.value;
|
||||
if (idx < this.mEventSeq.length) {
|
||||
matched = this.compareEvents(idx, aEvent);
|
||||
if (matched)
|
||||
this.mEventSeqIdx = idx;
|
||||
}
|
||||
|
||||
// Check if handled event matches expected event.
|
||||
var matched = this.compareEvents(idx, aEvent);
|
||||
// Check if handled event matches any expected async events.
|
||||
if (!matched) {
|
||||
for (idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
if (this.mEventSeq[idx].async) {
|
||||
matched = this.compareEvents(idx, aEvent);
|
||||
if (matched)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.dumpEventToDOM(aEvent, idx, matched);
|
||||
|
||||
if (matched) {
|
||||
this.checkEvent(idx, aEvent);
|
||||
invoker.wasCaught[idx] = true;
|
||||
this.mEventSeqIdx = idx;
|
||||
|
||||
// Get next expected event index.
|
||||
while (++idx < this.mEventSeq.length && this.mEventSeq[idx].unexpected);
|
||||
|
||||
// If the last expected event was processed, proceed next invoker in
|
||||
// timeout to ensure unexpected events for current invoker won't be
|
||||
// handled.
|
||||
if (idx == this.mEventSeq.length) {
|
||||
this.mEventSeqIdx = idx;
|
||||
this.processNextInvokerInTimeout();
|
||||
}
|
||||
this.prepareForExpectedEvent(invoker);
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
this.prepareForExpectedEvent =
|
||||
function eventQueue_prepareForExpectedEvent(aInvoker, aIdxObj)
|
||||
{
|
||||
// Nothing left, wait for next invoker.
|
||||
if (this.mEventSeqFinished)
|
||||
return false;
|
||||
|
||||
// Compute next expected sync event index.
|
||||
for (var idx = this.mEventSeqIdx + 1;
|
||||
idx < this.mEventSeq.length &&
|
||||
(this.mEventSeq[idx].unexpected || this.mEventSeq[idx].async);
|
||||
idx++);
|
||||
|
||||
// If no expected events were left, proceed to next invoker in timeout
|
||||
// to make sure unexpected events for current invoker aren't be handled.
|
||||
if (idx == this.mEventSeq.length) {
|
||||
var allHandled = true;
|
||||
for (var jdx = 0; jdx < this.mEventSeq.length; jdx++) {
|
||||
if (this.isEventExpected(jdx) && !aInvoker.wasCaught[jdx])
|
||||
allHandled = false;
|
||||
}
|
||||
|
||||
if (allHandled) {
|
||||
this.mEventSeqIdx = this.mEventSeq.length;
|
||||
this.mEventFinished = true;
|
||||
this.processNextInvokerInTimeout();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aIdxObj)
|
||||
aIdxObj.value = idx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
this.getInvoker = function eventQueue_getInvoker()
|
||||
{
|
||||
return this.mInvokers[this.mIndex];
|
||||
|
@ -405,18 +451,24 @@ function eventQueue(aEventType)
|
|||
aInvoker.eventSeq :
|
||||
[ new invokerChecker(this.mDefEventType, aInvoker.DOMNode) ];
|
||||
|
||||
for (var idx = 0; idx < this.mEventSeq.length; idx++)
|
||||
for (var idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
this.mEventSeq[idx].unexpected = false;
|
||||
if (!("async" in this.mEventSeq[idx]))
|
||||
this.mEventSeq[idx].async = false;
|
||||
}
|
||||
|
||||
var unexpectedSeq = aInvoker.unexpectedEventSeq;
|
||||
if (unexpectedSeq) {
|
||||
for (var idx = 0; idx < unexpectedSeq.length; idx++)
|
||||
for (var idx = 0; idx < unexpectedSeq.length; idx++) {
|
||||
unexpectedSeq[idx].unexpected = true;
|
||||
unexpectedSeq[idx].async = false;
|
||||
}
|
||||
|
||||
this.mEventSeq = this.mEventSeq.concat(unexpectedSeq);
|
||||
}
|
||||
|
||||
this.mEventSeqIdx = -1;
|
||||
this.mEventSeqFinished = false;
|
||||
|
||||
// Register event listeners
|
||||
if (this.mEventSeq) {
|
||||
|
@ -517,6 +569,10 @@ function eventQueue(aEventType)
|
|||
{
|
||||
return this.mEventSeq[aIdx].unexpected;
|
||||
}
|
||||
this.isEventExpected = function eventQueue_isEventExpected(aIdx)
|
||||
{
|
||||
return !this.mEventSeq[aIdx].unexpected;
|
||||
}
|
||||
|
||||
this.compareEvents = function eventQueue_compareEvents(aIdx, aEvent)
|
||||
{
|
||||
|
@ -598,20 +654,17 @@ function eventQueue(aEventType)
|
|||
gLogger.logToDOM(info);
|
||||
}
|
||||
|
||||
var currType = this.getEventTypeAsString(aExpectedEventIdx);
|
||||
var currTarget = this.getEventTarget(aExpectedEventIdx);
|
||||
if (!aMatch)
|
||||
return;
|
||||
|
||||
var msg = "EQ: ";
|
||||
var emphText = "";
|
||||
if (aMatch) {
|
||||
emphText = "matched ";
|
||||
var emphText = "matched ";
|
||||
|
||||
var consoleMsg = "*****\nEQ matched: " + currType + "\n*****";
|
||||
gLogger.logToConsole(consoleMsg);
|
||||
var currType = this.getEventTypeAsString(aExpectedEventIdx);
|
||||
var currTarget = this.getEventTarget(aExpectedEventIdx);
|
||||
var consoleMsg = "*****\nEQ matched: " + currType + "\n*****";
|
||||
gLogger.logToConsole(consoleMsg);
|
||||
|
||||
} else {
|
||||
msg += "expected";
|
||||
}
|
||||
msg += " event, type: " + currType + ", target: " + prettyName(currTarget);
|
||||
|
||||
gLogger.logToDOM(msg, true, emphText);
|
||||
|
@ -624,6 +677,7 @@ function eventQueue(aEventType)
|
|||
|
||||
this.mEventSeq = null;
|
||||
this.mEventSeqIdx = -1;
|
||||
this.mEventSeqFinished = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -896,9 +950,10 @@ function synthSelectAll(aNodeOrID, aCheckerOrEventSeq, aEventType)
|
|||
/**
|
||||
* Common invoker checker (see eventSeq of eventQueue).
|
||||
*/
|
||||
function invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
|
||||
function invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg, aIsAsync)
|
||||
{
|
||||
this.type = aEventType;
|
||||
this.async = aIsAsync;
|
||||
|
||||
this.__defineGetter__("target", invokerChecker_targetGetter);
|
||||
this.__defineSetter__("target", invokerChecker_targetSetter);
|
||||
|
@ -932,6 +987,15 @@ function invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
|
|||
this.mTargetFuncArg = aTargetFuncArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common invoker checker for async events.
|
||||
*/
|
||||
function asyncInvokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
|
||||
{
|
||||
this.__proto__ = new invokerChecker(aEventType, aTargetOrFunc,
|
||||
aTargetFuncArg, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Text inserted/removed events checker.
|
||||
*/
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
}
|
||||
|
||||
var invokerChecker = gOpenerWnd.invokerChecker;
|
||||
var asyncInvokerChecker = gOpenerWnd.asyncInvokerChecker;
|
||||
|
||||
const STATE_BUSY = gOpenerWnd.STATE_BUSY;
|
||||
const EVENT_DOCUMENT_LOAD_COMPLETE =
|
||||
|
@ -48,6 +49,8 @@
|
|||
const nsIAccessibleStateChangeEvent =
|
||||
gOpenerWnd.nsIAccessibleStateChangeEvent;
|
||||
|
||||
//gOpenerWnd.gA11yEventDumpToConsole = true; // debug
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Hacks to make xul:tabbrowser work.
|
||||
|
||||
|
@ -132,7 +135,7 @@
|
|||
this.eventSeq = [
|
||||
// We don't expect state change event for busy true since things happen
|
||||
// quickly and it's coalesced.
|
||||
new invokerChecker(EVENT_REORDER, getContainer),
|
||||
new asyncInvokerChecker(EVENT_REORDER, getContainer),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
@ -155,7 +158,7 @@
|
|||
|
||||
this.eventSeq = [
|
||||
new documentReloadChecker(true),
|
||||
new invokerChecker(EVENT_REORDER, getContainer),
|
||||
new asyncInvokerChecker(EVENT_REORDER, getContainer),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
@ -178,7 +181,7 @@
|
|||
|
||||
this.eventSeq = [
|
||||
new documentReloadChecker(false),
|
||||
new invokerChecker(EVENT_REORDER, getContainer),
|
||||
new asyncInvokerChecker(EVENT_REORDER, getContainer),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
@ -202,7 +205,7 @@
|
|||
this.eventSeq = [
|
||||
// We don't expect state change for busy true, load stopped events since
|
||||
// things happen quickly and it's coalesced.
|
||||
new invokerChecker(EVENT_REORDER, getContainer),
|
||||
new asyncInvokerChecker(EVENT_REORDER, getContainer),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
|
|
@ -357,6 +357,36 @@
|
|||
}
|
||||
}
|
||||
|
||||
function changeSrc(aID)
|
||||
{
|
||||
this.containerNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode)
|
||||
];
|
||||
|
||||
this.invoke = function changeSrc_invoke()
|
||||
{
|
||||
this.containerNode.src = "data:text/html,<html><input></html>";
|
||||
}
|
||||
|
||||
this.finalCheck = function changeSrc_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ INTERNAL_FRAME: [
|
||||
{ DOCUMENT: [
|
||||
{ ENTRY: [ ] }
|
||||
] };
|
||||
] };
|
||||
testAccessibleTree(this.containerNode, tree);
|
||||
}
|
||||
|
||||
this.getID() = function changeSrc_getID()
|
||||
{
|
||||
return "change src on iframe";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
|
@ -378,6 +408,7 @@
|
|||
gQueue.push(new removeBodyFromIFrameDoc("iframe"));
|
||||
gQueue.push(new insertElmUnderDocElmWhileBodyMissed("iframe"));
|
||||
gQueue.push(new insertBodyToIFrameDoc("iframe"));
|
||||
gQueue.push(new changeSrc("iframe"));
|
||||
|
||||
gQueue.invoke(); // SimpleTest.finish() will be called in the end
|
||||
}
|
||||
|
@ -394,6 +425,9 @@
|
|||
<a target="_blank"
|
||||
title="Elements inserted outside the body aren't accessible"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=608887">Mozilla Bug 608887</a>
|
||||
<a target="_blank"
|
||||
title="Reorder event for document must be fired after document initial tree creation"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=669263">Mozilla Bug 669263</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
|
|
@ -116,18 +116,7 @@ ifndef LIBXUL_SDK
|
|||
INSTALL_SDK = 1
|
||||
endif
|
||||
|
||||
ifneq (1_,$(if $(CROSS_COMPILE),1,0)_$(UNIVERSAL_BINARY))
|
||||
ifdef RUN_TEST_PROGRAM
|
||||
_ABS_RUN_TEST_PROGRAM = $(call core_abspath,$(RUN_TEST_PROGRAM))
|
||||
endif
|
||||
|
||||
GENERATE_CACHE = \
|
||||
$(_ABS_RUN_TEST_PROGRAM) $(LIBXUL_DIST)/bin/xpcshell$(BIN_SUFFIX) -g "$$PWD" -a "$$PWD" -f $(topsrcdir)/browser/installer/precompile_cache.js -e 'populate_startupcache("omni.jar", "startupCache.zip");' && \
|
||||
rm -rf jsloader && \
|
||||
$(UNZIP) startupCache.zip && \
|
||||
rm startupCache.zip && \
|
||||
$(ZIP) -r9m omni.jar jsloader
|
||||
endif
|
||||
GENERATE_CACHE = 1
|
||||
|
||||
include $(topsrcdir)/toolkit/mozapps/installer/packager.mk
|
||||
|
||||
|
|
|
@ -3325,6 +3325,41 @@ nsScriptSecurityManager::Observe(nsISupports* aObject, const char* aTopic,
|
|||
return rv;
|
||||
}
|
||||
|
||||
///////////////////////////////////
|
||||
// Default ObjectPrincipalFinder //
|
||||
///////////////////////////////////
|
||||
|
||||
// The default JSSecurityCallbacks::findObjectPrincipals is necessary since
|
||||
// scripts run (and ask for object principals) during startup before
|
||||
// nsJSRuntime::Init() has been called (which resets findObjectPrincipals).
|
||||
|
||||
// Defined NS_EXPORT for linkage with debug-only assert in xpcshell
|
||||
NS_EXPORT JSPrincipals *
|
||||
NS_DefaultObjectPrincipalFinder(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
nsScriptSecurityManager *ssm = nsScriptSecurityManager::GetScriptSecurityManager();
|
||||
if (!ssm) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
nsresult rv = ssm->GetObjectPrincipal(cx, obj, getter_AddRefs(principal));
|
||||
if (NS_FAILED(rv) || !principal) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
JSPrincipals *jsPrincipals = nsnull;
|
||||
principal->GetJSPrincipals(cx, &jsPrincipals);
|
||||
|
||||
// nsIPrincipal::GetJSPrincipals() returns a strong reference to the
|
||||
// JS principals, but the caller of this function expects a weak
|
||||
// reference. So we need to release here.
|
||||
|
||||
JSPRINCIPALS_DROP(cx, jsPrincipals);
|
||||
|
||||
return jsPrincipals;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Constructor, Destructor, Initialization //
|
||||
/////////////////////////////////////////////
|
||||
|
@ -3397,7 +3432,7 @@ nsresult nsScriptSecurityManager::Init()
|
|||
static JSSecurityCallbacks securityCallbacks = {
|
||||
CheckObjectAccess,
|
||||
NULL,
|
||||
NULL,
|
||||
NS_DefaultObjectPrincipalFinder,
|
||||
ContentSecurityPolicyPermitsJSAction
|
||||
};
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::layout;
|
||||
typedef FrameMetrics::ViewID ViewID;
|
||||
|
||||
#include "jsapi.h"
|
||||
|
@ -170,7 +171,7 @@ nsContentView::Update(const ViewConfig& aConfig)
|
|||
|
||||
// View changed. Try to locate our subdoc frame and invalidate
|
||||
// it if found.
|
||||
if (!mOwnerContent) {
|
||||
if (!mFrameLoader) {
|
||||
if (IsRoot()) {
|
||||
// Oops, don't have a frame right now. That's OK; the view
|
||||
// config persists and will apply to the next frame we get, if we
|
||||
|
@ -182,10 +183,13 @@ nsContentView::Update(const ViewConfig& aConfig)
|
|||
}
|
||||
}
|
||||
|
||||
nsIFrame* frame = mOwnerContent->GetPrimaryFrame();
|
||||
if (RenderFrameParent* rfp = mFrameLoader->GetCurrentRemoteFrame()) {
|
||||
rfp->ContentViewScaleChanged(this);
|
||||
}
|
||||
|
||||
// XXX could be clever here and compute a smaller invalidation
|
||||
// rect
|
||||
nsIFrame* frame = mFrameLoader->GetPrimaryFrameOfOwningContent();
|
||||
InvalidateFrame(frame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -127,11 +127,11 @@ public:
|
|||
float mYScale;
|
||||
};
|
||||
|
||||
nsContentView(nsIContent* aOwnerContent, ViewID aScrollId,
|
||||
nsContentView(nsFrameLoader* aFrameLoader, ViewID aScrollId,
|
||||
ViewConfig aConfig = ViewConfig())
|
||||
: mViewportSize(0, 0)
|
||||
, mContentSize(0, 0)
|
||||
, mOwnerContent(aOwnerContent)
|
||||
, mFrameLoader(aFrameLoader)
|
||||
, mScrollId(aScrollId)
|
||||
, mConfig(aConfig)
|
||||
{}
|
||||
|
@ -151,7 +151,7 @@ public:
|
|||
nsSize mViewportSize;
|
||||
nsSize mContentSize;
|
||||
|
||||
nsIContent *mOwnerContent; // WEAK
|
||||
nsFrameLoader* mFrameLoader; // WEAK
|
||||
|
||||
private:
|
||||
nsresult Update(const ViewConfig& aConfig);
|
||||
|
|
|
@ -1017,8 +1017,8 @@ nsWebSocket::ParseURL(const nsString& aURL)
|
|||
rv = parsedURL->GetQuery(query);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SYNTAX_ERR);
|
||||
|
||||
nsXPIDLCString origin;
|
||||
rv = mPrincipal->GetOrigin(getter_Copies(origin));
|
||||
nsCString origin;
|
||||
rv = nsContentUtils::GetASCIIOrigin(mPrincipal, origin);
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_SYNTAX_ERR);
|
||||
|
||||
if (scheme.LowerCaseEqualsLiteral("ws")) {
|
||||
|
|
|
@ -2875,6 +2875,20 @@ nsGenericHTMLFormElement::FormIdUpdated(Element* aOldElement,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsGenericHTMLFormElement::IsElementDisabledForEvents(PRUint32 aMessage,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
PRBool disabled = IsDisabled();
|
||||
if (!disabled && aFrame) {
|
||||
const nsStyleUserInterface* uiStyle = aFrame->GetStyleUserInterface();
|
||||
disabled = uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
||||
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED;
|
||||
|
||||
}
|
||||
return disabled && aMessage != NS_MOUSE_MOVE;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
|
||||
Element* aFormIdElement)
|
||||
|
|
|
@ -946,6 +946,9 @@ protected:
|
|||
static PRBool FormIdUpdated(Element* aOldElement, Element* aNewElement,
|
||||
void* aData);
|
||||
|
||||
// Returns true if the event should not be handled from PreHandleEvent
|
||||
virtual PRBool IsElementDisabledForEvents(PRUint32 aMessage, nsIFrame* aFrame);
|
||||
|
||||
// The focusability state of this form control. eUnfocusable means that it
|
||||
// shouldn't be focused at all, eInactiveWindow means it's in an inactive
|
||||
// window, eActiveWindow means it's in an active window.
|
||||
|
|
|
@ -282,23 +282,15 @@ nsHTMLButtonElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
nsresult
|
||||
nsHTMLButtonElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Do not process any DOM events if the element is disabled
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsDisabled()) {
|
||||
return NS_OK;
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
nsIFrame* formFrame = NULL;
|
||||
if (formControlFrame) {
|
||||
formFrame = do_QueryFrame(formControlFrame);
|
||||
}
|
||||
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
|
||||
if (formControlFrame) {
|
||||
nsIFrame* formFrame = do_QueryFrame(formControlFrame);
|
||||
if (formFrame) {
|
||||
const nsStyleUserInterface* uiStyle = formFrame->GetStyleUserInterface();
|
||||
|
||||
if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
||||
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED)
|
||||
return NS_OK;
|
||||
}
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsElementDisabledForEvents(aVisitor.mEvent->message, formFrame)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Track whether we're in the outermost Dispatch invocation that will
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsIForm.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
|
||||
|
@ -109,7 +110,7 @@ nsHTMLFieldSetElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
{
|
||||
// Do not process any DOM events if the element is disabled.
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsDisabled()) {
|
||||
if (IsElementDisabledForEvents(aVisitor.mEvent->message, NULL)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1854,24 +1854,10 @@ nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
|||
{
|
||||
// Do not process any DOM events if the element is disabled
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsDisabled()) {
|
||||
if (IsElementDisabledForEvents(aVisitor.mEvent->message, GetPrimaryFrame())) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For some reason or another we also need to check if the style shows us
|
||||
// as disabled.
|
||||
{
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
if (frame) {
|
||||
const nsStyleUserInterface* uiStyle = frame->GetStyleUserInterface();
|
||||
|
||||
if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
||||
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the editor if needed.
|
||||
if (NeedToInitializeEditorForEvent(aVisitor)) {
|
||||
nsITextControlFrame* textControlFrame = do_QueryFrame(GetPrimaryFrame());
|
||||
|
|
|
@ -1504,24 +1504,15 @@ nsHTMLSelectElement::GetAttributeMappingFunction() const
|
|||
nsresult
|
||||
nsHTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
// Do not process any DOM events if the element is disabled
|
||||
// XXXsmaug This is not the right thing to do. But what is?
|
||||
if (IsDisabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
nsIFrame* formFrame = nsnull;
|
||||
if (formControlFrame) {
|
||||
formFrame = do_QueryFrame(formControlFrame);
|
||||
}
|
||||
|
||||
if (formControlFrame &&
|
||||
(formFrame = do_QueryFrame(formControlFrame))) {
|
||||
const nsStyleUserInterface* uiStyle = formFrame->GetStyleUserInterface();
|
||||
|
||||
if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
||||
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) {
|
||||
return NS_OK;
|
||||
}
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsElementDisabledForEvents(aVisitor.mEvent->message, formFrame)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::PreHandleEvent(aVisitor);
|
||||
|
|
|
@ -677,23 +677,15 @@ nsHTMLTextAreaElement::GetAttributeMappingFunction() const
|
|||
nsresult
|
||||
nsHTMLTextAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Do not process any DOM events if the element is disabled
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsDisabled()) {
|
||||
return NS_OK;
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
nsIFrame* formFrame = NULL;
|
||||
if (formControlFrame) {
|
||||
formFrame = do_QueryFrame(formControlFrame);
|
||||
}
|
||||
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
nsIFrame* formFrame = nsnull;
|
||||
|
||||
if (formControlFrame &&
|
||||
(formFrame = do_QueryFrame(formControlFrame))) {
|
||||
const nsStyleUserInterface* uiStyle = formFrame->GetStyleUserInterface();
|
||||
|
||||
if (uiStyle->mUserInput == NS_STYLE_USER_INPUT_NONE ||
|
||||
uiStyle->mUserInput == NS_STYLE_USER_INPUT_DISABLED) {
|
||||
return NS_OK;
|
||||
}
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
if (IsElementDisabledForEvents(aVisitor.mEvent->message, formFrame)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't dispatch a second select event if we are already handling
|
||||
|
|
|
@ -91,6 +91,7 @@ _TEST_FILES = \
|
|||
bug277890_iframe.html \
|
||||
bug277890_load.html \
|
||||
test_bug277890.html \
|
||||
test_bug274626.html \
|
||||
test_bug287465.html \
|
||||
test_bug209275.xhtml \
|
||||
file_bug209275_1.html \
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=274626
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 274626</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=274626">Mozilla Bug 274626</a>
|
||||
<br>
|
||||
|
||||
<input id='textbox_enabled' title='hello' value='hello' />
|
||||
<input id='textbox_disabled' title='hello' value='hello' disabled/>
|
||||
|
||||
<br>
|
||||
<input id='input_button_enabled' title='hello' value='hello' type='button' />
|
||||
<input id='input_button_disabled' title='hello' value='hello' type='button' disabled />
|
||||
|
||||
<br>
|
||||
<input id='checkbox_enabled' title='hello' type='checkbox'>hello</input>
|
||||
<input id='checkbox_disabled' title='hello' type='checkbox' disabled >hello</input>
|
||||
|
||||
<br>
|
||||
<button id='button_enabled' title='hello' value='hello' type='button'>test</button>
|
||||
<button id='button_disabled' title='hello' value='hello' type='button' disabled>test</button>
|
||||
|
||||
<br>
|
||||
<textarea id='textarea_enabled' title='hello' value='hello' onclick="alert('click event');"> </textarea>
|
||||
<textarea id='textarea_disabled' title='hello' value='hello' onclick="alert('click event');" disabled></textarea>
|
||||
|
||||
|
||||
<br>
|
||||
<select id='select_enabled' title='hello' onclick="alert('click event');">
|
||||
<option value='item1'>item1</option>
|
||||
<option value='item2'>item2</option>
|
||||
</select>
|
||||
<select id='select_disabled' title='hello' onclick="alert('click event');" disabled>
|
||||
<option value='item1'>item1</option>
|
||||
<option value='item2'>item2</option>
|
||||
</select>
|
||||
|
||||
<br>
|
||||
<form>
|
||||
<fieldset id='fieldset_enabled' title='hello' onclick="alert('click event');">
|
||||
<legend>Enabled fieldset:</legend>
|
||||
Name: <input type='text' size='30' /><br />
|
||||
Email: <input type='text' size='30' /><br />
|
||||
Date of birth: <input type='text' size='10' />
|
||||
</fieldset>
|
||||
</form>
|
||||
<form>
|
||||
<fieldset id='fieldset_disabled' title='hello' onclick="alert('click event');" disabled>
|
||||
<legend>Disabled fieldset:</legend>
|
||||
Name: <input type='text' size='30' /><br />
|
||||
Email: <input type='text' size='30' /><br />
|
||||
Date of birth: <input type='text' size='10' />
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
/** Test for Bug 274626 **/
|
||||
|
||||
function HandlesMouseMove(evt) {
|
||||
evt.target.handlesMouseMove = true;
|
||||
}
|
||||
|
||||
var controls=["textbox_enabled","textbox_disabled",
|
||||
"input_button_enabled", "input_button_disabled", "checkbox_enabled",
|
||||
"checkbox_disabled", "button_enabled", "button_disabled",
|
||||
"textarea_enabled", "textarea_disabled", "select_enabled",
|
||||
"select_disabled", "fieldset_enabled", "fieldset_disabled"];
|
||||
|
||||
for each(id in controls) {
|
||||
var ctrl = document.getElementById(id);
|
||||
ctrl.addEventListener('mousemove', HandlesMouseMove, false);
|
||||
ctrl.handlesMouseMove = false;
|
||||
var evt = document.createEvent("MouseEvents");
|
||||
evt.initMouseEvent("mousemove", true, true, window,
|
||||
0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
ctrl.dispatchEvent(evt);
|
||||
|
||||
// Mouse move events are what causes tooltips to show up.
|
||||
// Before this fix we would not allow mouse move events to go through
|
||||
// which in turn did not allow tooltips to be displayed.
|
||||
// This test will ensure that all HTML elements handle mouse move events
|
||||
// so that tooltips can be displayed
|
||||
ok(ctrl.handlesMouseMove, "Disabled element need mouse move for tooltips");
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -2585,7 +2585,12 @@ nsHTMLDocument::DeferredContentEditableCountChange(nsIContent *aElement)
|
|||
NS_ENSURE_SUCCESS(rv, );
|
||||
|
||||
rv = range->SelectNode(node);
|
||||
NS_ENSURE_SUCCESS(rv, );
|
||||
if (NS_FAILED(rv)) {
|
||||
// The node might be detached from the document at this point,
|
||||
// which would cause this call to fail. In this case, we can
|
||||
// safely ignore the contenteditable count change.
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInlineSpellChecker> spellChecker;
|
||||
rv = editor->GetInlineSpellChecker(PR_FALSE,
|
||||
|
|
|
@ -182,11 +182,9 @@ nsresult nsOggCodecState::PageIn(ogg_page* aPage) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsOggCodecState::PacketOutUntilGranulepos()
|
||||
{
|
||||
nsresult nsOggCodecState::PacketOutUntilGranulepos(PRBool& aFoundGranulepos) {
|
||||
int r;
|
||||
PRBool foundGp = PR_FALSE;
|
||||
aFoundGranulepos = PR_FALSE;
|
||||
// Extract packets from the sync state until either no more packets
|
||||
// come out, or we get a data packet with non -1 granulepos.
|
||||
do {
|
||||
|
@ -202,15 +200,15 @@ nsOggCodecState::PacketOutUntilGranulepos()
|
|||
// then use the granulepos to figure out the granulepos of the
|
||||
// preceeding packets.
|
||||
mUnstamped.AppendElement(clone);
|
||||
foundGp = packet.granulepos != -1;
|
||||
aFoundGranulepos = packet.granulepos > 0;
|
||||
}
|
||||
}
|
||||
} while (r != 0 && !foundGp);
|
||||
} while (r != 0 && !aFoundGranulepos);
|
||||
if (ogg_stream_check(&mState)) {
|
||||
NS_WARNING("Unrecoverable error in ogg_stream_packetout");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return foundGp;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTheoraState::nsTheoraState(ogg_page* aBosPage) :
|
||||
|
@ -377,7 +375,10 @@ nsTheoraState::PageIn(ogg_page* aPage)
|
|||
"Page must be for this stream!");
|
||||
if (ogg_stream_pagein(&mState, aPage) == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRBool foundGp = PacketOutUntilGranulepos();
|
||||
PRBool foundGp;
|
||||
nsresult res = PacketOutUntilGranulepos(foundGp);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
if (foundGp && mDoneReadingHeaders) {
|
||||
// We've found a packet with a granulepos, and we've loaded our metadata
|
||||
// and initialized our decoder. Determine granulepos of buffered packets.
|
||||
|
@ -622,7 +623,10 @@ nsVorbisState::PageIn(ogg_page* aPage)
|
|||
"Page must be for this stream!");
|
||||
if (ogg_stream_pagein(&mState, aPage) == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRBool foundGp = PacketOutUntilGranulepos();
|
||||
PRBool foundGp;
|
||||
nsresult res = PacketOutUntilGranulepos(foundGp);
|
||||
if (NS_FAILED(res))
|
||||
return res;
|
||||
if (foundGp && mDoneReadingHeaders) {
|
||||
// We've found a packet with a granulepos, and we've loaded our metadata
|
||||
// and initialized our decoder. Determine granulepos of buffered packets.
|
||||
|
|
|
@ -202,7 +202,7 @@ protected:
|
|||
// the granulepos of the packets in mUnstamped can be inferred, and they
|
||||
// can be pushed over to mPackets. Used by PageIn() implementations in
|
||||
// subclasses.
|
||||
PRBool PacketOutUntilGranulepos();
|
||||
nsresult PacketOutUntilGranulepos(PRBool& aFoundGranulepos);
|
||||
|
||||
// Temporary buffer in which to store packets while we're reading packets
|
||||
// in order to capture granulepos.
|
||||
|
|
|
@ -70,9 +70,8 @@ nsresult nsRawReader::ResetDecode()
|
|||
|
||||
nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||
{
|
||||
NS_ASSERTION(mDecoder->OnStateMachineThread(),
|
||||
"Should be on state machine thread.");
|
||||
mozilla::ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(),
|
||||
"Should be on decode thread.");
|
||||
|
||||
nsMediaStream* stream = mDecoder->GetCurrentStream();
|
||||
NS_ASSERTION(stream, "Decoder has no media stream");
|
||||
|
@ -133,7 +132,6 @@ nsresult nsRawReader::ReadMetadata(nsVideoInfo* aInfo)
|
|||
|
||||
PRInt64 length = stream->GetLength();
|
||||
if (length != -1) {
|
||||
mozilla::ReentrantMonitorAutoExit autoExitMonitor(mReentrantMonitor);
|
||||
mozilla::ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor());
|
||||
mDecoder->GetStateMachine()->SetDuration(USECS_PER_S *
|
||||
(length - sizeof(nsRawVideoHeader)) /
|
||||
|
@ -178,9 +176,8 @@ PRBool nsRawReader::ReadFromStream(nsMediaStream *aStream, PRUint8* aBuf,
|
|||
PRBool nsRawReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
|
||||
PRInt64 aTimeThreshold)
|
||||
{
|
||||
mozilla::ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
|
||||
NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
|
||||
"Should be on state machine thread or decode thread.");
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(),
|
||||
"Should be on decode thread.");
|
||||
|
||||
// Record number of frames decoded and parsed. Automatically update the
|
||||
// stats counters using the AutoNotifyDecoded stack-based class.
|
||||
|
@ -261,9 +258,8 @@ PRBool nsRawReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
|
|||
|
||||
nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime)
|
||||
{
|
||||
mozilla::ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
|
||||
NS_ASSERTION(mDecoder->OnStateMachineThread(),
|
||||
"Should be on state machine thread.");
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(),
|
||||
"Should be on decode thread.");
|
||||
|
||||
nsMediaStream *stream = mDecoder->GetCurrentStream();
|
||||
NS_ASSERTION(stream, "Decoder has no media stream");
|
||||
|
@ -292,7 +288,6 @@ nsresult nsRawReader::Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime,
|
|||
}
|
||||
|
||||
{
|
||||
mozilla::ReentrantMonitorAutoExit autoMonitorExit(mReentrantMonitor);
|
||||
mozilla::ReentrantMonitorAutoEnter autoMonitor(mDecoder->GetReentrantMonitor());
|
||||
if (mDecoder->GetDecodeState() ==
|
||||
nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
|
||||
|
|
До Ширина: | Высота: | Размер: 355 B После Ширина: | Высота: | Размер: 355 B |
|
@ -34,4 +34,4 @@ load 608295-1.html
|
|||
load 611927-1.svg
|
||||
load 615002-1.svg
|
||||
load 615872-1.svg
|
||||
load 665335-1.svg
|
||||
load 665334-1.svg
|
||||
|
|
|
@ -557,7 +557,9 @@ nsEditingSession::RemoveListenersAndControllers(nsIDOMWindow *aWindow,
|
|||
NS_IMETHODIMP
|
||||
nsEditingSession::TearDownEditorOnWindow(nsIDOMWindow *aWindow)
|
||||
{
|
||||
NS_ENSURE_TRUE(mDoneSetup, NS_OK);
|
||||
if (!mDoneSetup) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(aWindow, NS_ERROR_NULL_POINTER);
|
||||
|
||||
|
|
|
@ -1235,11 +1235,14 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, PRBool *aCancel)
|
|||
// Adjust selection to prevent insertion after a moz-BR.
|
||||
// this next only works for collapsed selections right now,
|
||||
// because selection is a pain to work with when not collapsed.
|
||||
// (no good way to extend start or end of selection)
|
||||
// (no good way to extend start or end of selection), so we ignore
|
||||
// those types of selections.
|
||||
PRBool bCollapsed;
|
||||
res = aSelection->GetIsCollapsed(&bCollapsed);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(bCollapsed, NS_OK);
|
||||
if (!bCollapsed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// if we are after a mozBR in the same block, then move selection
|
||||
// to be before it
|
||||
|
@ -3502,7 +3505,9 @@ nsHTMLEditRules::DidMakeBasicBlock(nsISelection *aSelection,
|
|||
PRBool isCollapsed;
|
||||
nsresult res = aSelection->GetIsCollapsed(&isCollapsed);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(isCollapsed, NS_OK);
|
||||
if (!isCollapsed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
PRInt32 offset;
|
||||
|
@ -7533,7 +7538,9 @@ nsHTMLEditRules::PinSelectionToNewBlock(nsISelection *aSelection)
|
|||
PRBool bCollapsed;
|
||||
nsresult res = aSelection->GetIsCollapsed(&bCollapsed);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(bCollapsed, res);
|
||||
if (!bCollapsed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// get the (collapsed) selection location
|
||||
nsCOMPtr<nsIDOMNode> selNode, temp;
|
||||
|
@ -7605,7 +7612,9 @@ nsHTMLEditRules::CheckInterlinePosition(nsISelection *aSelection)
|
|||
PRBool bCollapsed;
|
||||
nsresult res = aSelection->GetIsCollapsed(&bCollapsed);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(bCollapsed, res);
|
||||
if (!bCollapsed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// get the (collapsed) selection location
|
||||
nsCOMPtr<nsIDOMNode> selNode, node;
|
||||
|
@ -7649,7 +7658,9 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
|
|||
PRBool bCollapsed;
|
||||
nsresult res = aSelection->GetIsCollapsed(&bCollapsed);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(bCollapsed, res);
|
||||
if (!bCollapsed) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// get the (collapsed) selection location
|
||||
nsCOMPtr<nsIDOMNode> selNode, temp;
|
||||
|
@ -8411,7 +8422,9 @@ nsHTMLEditRules::DidCreateNode(const nsAString& aTag,
|
|||
PRInt32 aPosition,
|
||||
nsresult aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
// assumption that Join keeps the righthand node
|
||||
nsresult res = mUtilRange->SelectNode(aNode);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
@ -8433,7 +8446,9 @@ nsHTMLEditRules::DidInsertNode(nsIDOMNode *aNode,
|
|||
PRInt32 aPosition,
|
||||
nsresult aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult res = mUtilRange->SelectNode(aNode);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = UpdateDocChangeRange(mUtilRange);
|
||||
|
@ -8444,7 +8459,9 @@ nsHTMLEditRules::DidInsertNode(nsIDOMNode *aNode,
|
|||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::WillDeleteNode(nsIDOMNode *aChild)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult res = mUtilRange->SelectNode(aChild);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = UpdateDocChangeRange(mUtilRange);
|
||||
|
@ -8472,7 +8489,9 @@ nsHTMLEditRules::DidSplitNode(nsIDOMNode *aExistingRightNode,
|
|||
nsIDOMNode *aNewLeftNode,
|
||||
nsresult aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult res = mUtilRange->SetStart(aNewLeftNode, 0);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
res = mUtilRange->SetEnd(aExistingRightNode, 0);
|
||||
|
@ -8485,7 +8504,9 @@ nsHTMLEditRules::DidSplitNode(nsIDOMNode *aExistingRightNode,
|
|||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsIDOMNode *aParent)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
// remember split point
|
||||
nsresult res = nsEditor::GetLengthOfDOMNode(aLeftNode, mJoinOffset);
|
||||
return res;
|
||||
|
@ -8498,7 +8519,9 @@ nsHTMLEditRules::DidJoinNodes(nsIDOMNode *aLeftNode,
|
|||
nsIDOMNode *aParent,
|
||||
nsresult aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
// assumption that Join keeps the righthand node
|
||||
nsresult res = mUtilRange->SetStart(aRightNode, mJoinOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
@ -8522,7 +8545,9 @@ nsHTMLEditRules::DidInsertText(nsIDOMCharacterData *aTextNode,
|
|||
const nsAString &aString,
|
||||
nsresult aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
PRInt32 length = aString.Length();
|
||||
nsCOMPtr<nsIDOMNode> theNode = do_QueryInterface(aTextNode);
|
||||
nsresult res = mUtilRange->SetStart(theNode, aOffset);
|
||||
|
@ -8547,7 +8572,9 @@ nsHTMLEditRules::DidDeleteText(nsIDOMCharacterData *aTextNode,
|
|||
PRInt32 aLength,
|
||||
nsresult aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> theNode = do_QueryInterface(aTextNode);
|
||||
nsresult res = mUtilRange->SetStart(theNode, aOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
@ -8560,7 +8587,9 @@ nsHTMLEditRules::DidDeleteText(nsIDOMCharacterData *aTextNode,
|
|||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::WillDeleteRange(nsIDOMRange *aRange)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
// get the (collapsed) selection location
|
||||
return UpdateDocChangeRange(aRange);
|
||||
}
|
||||
|
@ -8574,7 +8603,9 @@ nsHTMLEditRules::DidDeleteRange(nsIDOMRange *aRange)
|
|||
NS_IMETHODIMP
|
||||
nsHTMLEditRules::WillDeleteSelection(nsISelection *aSelection)
|
||||
{
|
||||
NS_ENSURE_TRUE(mListenerEnabled, NS_OK);
|
||||
if (!mListenerEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
// get the (collapsed) selection location
|
||||
nsCOMPtr<nsIDOMNode> selNode;
|
||||
PRInt32 selOffset;
|
||||
|
|
|
@ -393,7 +393,9 @@ nsHTMLEditUtils::IsMailCite(nsIDOMNode *node)
|
|||
{
|
||||
NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsMailCite");
|
||||
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(node);
|
||||
NS_ENSURE_TRUE(elem, PR_FALSE);
|
||||
if (!elem) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsAutoString attrName (NS_LITERAL_STRING("type"));
|
||||
|
||||
// don't ask me why, but our html mailcites are id'd by "type=cite"...
|
||||
|
|
|
@ -4282,12 +4282,14 @@ void nsHTMLEditor::IsTextPropertySetByContent(nsIDOMNode *aNode,
|
|||
PRBool
|
||||
nsHTMLEditor::IsNodeInActiveEditor(nsIDOMNode* aNode)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
if (!node) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsIContent* activeEditingHost = GetActiveEditingHost();
|
||||
if (!activeEditingHost) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
NS_ENSURE_TRUE(node, PR_FALSE);
|
||||
return nsContentUtils::ContentIsDescendantOf(node, activeEditingHost);
|
||||
}
|
||||
|
||||
|
@ -4596,7 +4598,10 @@ nsHTMLEditor::GetPriorHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outN
|
|||
{
|
||||
res = node->GetPreviousSibling(getter_AddRefs(temp));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(temp, NS_OK); // return null sibling
|
||||
if (!temp) {
|
||||
// return null sibling
|
||||
return NS_OK;
|
||||
}
|
||||
// if it's editable, we're done
|
||||
if (IsEditable(temp)) break;
|
||||
// otherwise try again
|
||||
|
@ -4619,7 +4624,10 @@ nsHTMLEditor::GetPriorHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMP
|
|||
NS_ENSURE_TRUE(outNode && inParent, NS_ERROR_NULL_POINTER);
|
||||
nsresult res = NS_OK;
|
||||
*outNode = nsnull;
|
||||
NS_ENSURE_TRUE(inOffset, NS_OK); // return null sibling if at offset zero
|
||||
if (inOffset <= 0) {
|
||||
// return null sibling if at offset zero
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset-1);
|
||||
if (node && IsEditable(node)) {
|
||||
*outNode = node;
|
||||
|
@ -4647,7 +4655,10 @@ nsHTMLEditor::GetNextHTMLSibling(nsIDOMNode *inNode, nsCOMPtr<nsIDOMNode> *outNo
|
|||
{
|
||||
res = node->GetNextSibling(getter_AddRefs(temp));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_TRUE(temp, NS_OK); // return null sibling
|
||||
if (!temp) {
|
||||
// return null sibling
|
||||
return NS_OK;
|
||||
}
|
||||
// if it's editable, we're done
|
||||
if (IsEditable(temp)) break;
|
||||
// otherwise try again
|
||||
|
@ -4671,7 +4682,10 @@ nsHTMLEditor::GetNextHTMLSibling(nsIDOMNode *inParent, PRInt32 inOffset, nsCOMPt
|
|||
nsresult res = NS_OK;
|
||||
*outNode = nsnull;
|
||||
nsCOMPtr<nsIDOMNode> node = nsEditor::GetChildAt(inParent,inOffset);
|
||||
NS_ENSURE_TRUE(node, NS_OK); // return null sibling if no sibling
|
||||
if (!node) {
|
||||
// return null sibling if no sibling
|
||||
return NS_OK;
|
||||
}
|
||||
if (node && IsEditable(node)) {
|
||||
*outNode = node;
|
||||
return res;
|
||||
|
|
|
@ -62,8 +62,6 @@
|
|||
/*
|
||||
* nsHTMLEditorEventListener implementation
|
||||
*
|
||||
* The only reason we need this is so a context mouse-click
|
||||
* moves the caret or selects an element as it does for normal click
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -134,17 +132,8 @@ nsHTMLEditorEventListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
nsresult res = mouseEvent->GetButton(&buttonNumber);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
PRBool isContextClick;
|
||||
PRBool isContextClick = buttonNumber == 2;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// Ctrl+Click for context menu
|
||||
res = mouseEvent->GetCtrlKey(&isContextClick);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
#else
|
||||
// Right mouse button for Windows, UNIX
|
||||
isContextClick = buttonNumber == 2;
|
||||
#endif
|
||||
|
||||
PRInt32 clickCount;
|
||||
res = mouseEvent->GetDetail(&clickCount);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
@ -245,14 +234,8 @@ nsHTMLEditorEventListener::MouseDown(nsIDOMEvent* aMouseEvent)
|
|||
}
|
||||
}
|
||||
|
||||
// XXX: should we call nsHTMLEditUtils::IsTableElement here?
|
||||
// that also checks for thead, tbody, tfoot
|
||||
if (nsTextEditUtils::IsBody(node) ||
|
||||
nsHTMLEditUtils::IsTableCellOrCaption(node) ||
|
||||
nsHTMLEditUtils::IsTableRow(node) ||
|
||||
nsHTMLEditUtils::IsTable(node))
|
||||
if (isContextClick && !nsHTMLEditUtils::IsImage(node))
|
||||
{
|
||||
// This will place caret just inside table cell or at start of body
|
||||
selection->Collapse(parent, offset);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -952,8 +952,10 @@ nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
|
|||
PRBool nsHTMLEditor::IsAtFrontOfNode(nsIDOMNode *aNode, PRInt32 aOffset)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, PR_FALSE); // oops
|
||||
NS_ENSURE_TRUE(aOffset, PR_TRUE);
|
||||
|
||||
if (!aOffset) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (IsTextNode(aNode))
|
||||
{
|
||||
return PR_FALSE;
|
||||
|
|
|
@ -2950,7 +2950,9 @@ nsHTMLEditor::GetCellFromRange(nsIDOMRange *aRange, nsIDOMElement **aCell)
|
|||
|
||||
nsCOMPtr<nsIDOMNode> childNode = GetChildAt(startParent, startOffset);
|
||||
// This means selection is probably at a text node (or end of doc?)
|
||||
NS_ENSURE_TRUE(childNode, NS_ERROR_FAILURE);
|
||||
if (!childNode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> endParent;
|
||||
res = aRange->GetEndContainer(getter_AddRefs(endParent));
|
||||
|
@ -3000,9 +3002,13 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMRange **aRange, nsIDOMElement **aCell)
|
|||
res = GetCellFromRange(range, aCell);
|
||||
// Failure here probably means selection is in a text node,
|
||||
// so there's no selected cell
|
||||
NS_ENSURE_SUCCESS(res, NS_EDITOR_ELEMENT_NOT_FOUND);
|
||||
if (NS_FAILED(res)) {
|
||||
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
// No cell means range was collapsed (cell was deleted)
|
||||
NS_ENSURE_TRUE(*aCell, NS_EDITOR_ELEMENT_NOT_FOUND);
|
||||
if (!*aCell) {
|
||||
return NS_EDITOR_ELEMENT_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (aRange)
|
||||
{
|
||||
|
|
|
@ -660,7 +660,10 @@ nsWSRunObject::AdjustWhitespace()
|
|||
// this routine examines a run of ws and tries to get rid of some unneeded nbsp's,
|
||||
// replacing them with regualr ascii space if possible. Keeping things simple
|
||||
// for now and just trying to fix up the trailing ws in the run.
|
||||
NS_ENSURE_TRUE(mLastNBSPNode, NS_OK); // nothing to do!
|
||||
if (!mLastNBSPNode) {
|
||||
// nothing to do!
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult res = NS_OK;
|
||||
WSFragment *curRun = mStartRun;
|
||||
while (curRun)
|
||||
|
|
|
@ -52,6 +52,7 @@ _TEST_FILES = \
|
|||
test_bug372345.html \
|
||||
test_bug410986.html \
|
||||
test_bug414526.html \
|
||||
test_bug417418.html \
|
||||
test_bug432225.html \
|
||||
test_bug439808.html \
|
||||
test_bug455992.html \
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=417418
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 417418</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=417418">Mozilla Bug 417418</a>
|
||||
<div id="display" contenteditable="true">
|
||||
<p id="coin">first paragraph</p>
|
||||
<p>second paragraph. <img id="img" src="green.png"></p>
|
||||
</div>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 417418 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTest);
|
||||
|
||||
function resetSelection() {
|
||||
window.getSelection().collapse(document.getElementById("coin"), 0);
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
var rightClick = {type: 'mousedown', button: 2},
|
||||
singleClick = {type: 'mousedown', button: 0};
|
||||
var selection = window.getSelection();
|
||||
|
||||
var div = document.getElementById('display');
|
||||
var img = document.getElementById('img');
|
||||
var divRect = div.getBoundingClientRect();
|
||||
var imgselected;
|
||||
|
||||
resetSelection();
|
||||
synthesizeMouse(div, divRect.width - 1, divRect.height - 1, rightClick);
|
||||
ok(selection.isCollapsed, "selection is not collapsed");
|
||||
|
||||
resetSelection();
|
||||
synthesizeMouse(div, divRect.width - 1, divRect.height - 1, singleClick);
|
||||
ok(selection.isCollapsed, "selection is not collapsed");
|
||||
|
||||
resetSelection();
|
||||
synthesizeMouseAtCenter(img, rightClick);
|
||||
imgselected = selection.anchorNode.isSameNode(img.parentNode) &&
|
||||
selection.anchorOffset === 1 &&
|
||||
selection.rangeCount === 1;
|
||||
ok(imgselected, "image is not selected");
|
||||
|
||||
resetSelection();
|
||||
synthesizeMouseAtCenter(img, singleClick);
|
||||
imgselected = selection.anchorNode.isSameNode(img.parentNode) &&
|
||||
selection.anchorOffset === 1 &&
|
||||
selection.rangeCount === 1;
|
||||
ok(imgselected, "image is not selected");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -4,8 +4,7 @@
|
|||
package="@ANDROID_PACKAGE_NAME@"
|
||||
android:installLocation="auto"
|
||||
android:versionCode="@ANDROID_VERSION_CODE@"
|
||||
android:versionName="@MOZ_APP_VERSION@"
|
||||
android:sharedUserId="@MOZ_ANDROID_SHARED_ID@">
|
||||
android:versionName="@MOZ_APP_VERSION@">
|
||||
<uses-sdk android:minSdkVersion="5"
|
||||
android:targetSdkVersion="5"/>
|
||||
|
||||
|
|
|
@ -262,12 +262,21 @@ abstract public class GeckoApp
|
|||
if (GeckoAppShell.getFreeSpace() > GeckoAppShell.kFreeSpaceThreshold &&
|
||||
(!libxulFile.exists() ||
|
||||
new File(getApplication().getPackageResourcePath()).lastModified()
|
||||
>= libxulFile.lastModified()))
|
||||
>= libxulFile.lastModified())) {
|
||||
surfaceView.mSplashStatusMsg =
|
||||
getResources().getString(R.string.splash_screen_installing_libs);
|
||||
else
|
||||
File[] libs = cacheFile.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
return name.endsWith(".so");
|
||||
}
|
||||
});
|
||||
for (int i = 0; i < libs.length; i++) {
|
||||
libs[i].delete();
|
||||
}
|
||||
} else {
|
||||
surfaceView.mSplashStatusMsg =
|
||||
getResources().getString(R.string.splash_screen_loading);
|
||||
}
|
||||
mLibLoadThread.start();
|
||||
}
|
||||
|
||||
|
|
|
@ -101,17 +101,9 @@ GARBAGE_DIRS += classes res
|
|||
ifeq ($(MOZ_APP_NAME),fennec)
|
||||
ICON_PATH = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/fennec_48x48.png
|
||||
ICON_PATH_HDPI = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/fennec_72x72.png
|
||||
ifeq (org.mozilla.fennec_unofficial,$(ANDROID_PACKAGE_NAME))
|
||||
DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.fennec_unofficial.sharedID"
|
||||
else ifeq (,$(MOZ_OFFICIAL_BRANDING))
|
||||
DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.fennec.sharedID"
|
||||
else
|
||||
DEFINES += -DMOZ_ANDROID_SHARED_ID="org.mozilla.firefox.sharedID"
|
||||
endif
|
||||
else
|
||||
ICON_PATH = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/icon48.png
|
||||
ICON_PATH_HDPI = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/icon64.png
|
||||
DEFINES += -DMOZ_ANDROID_SHARED_ID="$(ANDROID_PACKAGE_NAME).sharedID"
|
||||
endif
|
||||
|
||||
RES_LAYOUT = \
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// |jit-test| error:TypeError
|
||||
|
||||
print(evalcx("#1=@o"))
|
|
@ -0,0 +1,8 @@
|
|||
for each(let y in [0, 0]) {
|
||||
eval("\
|
||||
for each(e in[0,0,0,0,0,0,0,0]) {\
|
||||
x = undefined\
|
||||
}\
|
||||
")
|
||||
}
|
||||
|
|
@ -919,9 +919,7 @@ array_fix(JSContext *cx, JSObject *obj, bool *success, AutoIdVector *props)
|
|||
|
||||
Class js_ArrayClass = {
|
||||
"Array",
|
||||
Class::NON_NATIVE |
|
||||
JSCLASS_HAS_PRIVATE |
|
||||
JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
Class::NON_NATIVE | JSCLASS_HAS_PRIVATE | JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
|
||||
PropertyStub, /* addProperty */
|
||||
PropertyStub, /* delProperty */
|
||||
PropertyStub, /* getProperty */
|
||||
|
@ -2609,8 +2607,6 @@ array_slice(JSContext *cx, uintN argc, Value *vp)
|
|||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#if JS_HAS_ARRAY_EXTRAS
|
||||
|
||||
static JSBool
|
||||
array_indexOfHelper(JSContext *cx, JSBool isLast, uintN argc, Value *vp)
|
||||
{
|
||||
|
@ -2931,7 +2927,6 @@ array_every(JSContext *cx, uintN argc, Value *vp)
|
|||
{
|
||||
return array_extra(cx, EVERY, argc, vp);
|
||||
}
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
array_isArray(JSContext *cx, uintN argc, Value *vp)
|
||||
|
@ -2965,7 +2960,6 @@ static JSFunctionSpec array_methods[] = {
|
|||
JS_FN("concat", array_concat, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("slice", array_slice, 2,JSFUN_GENERIC_NATIVE),
|
||||
|
||||
#if JS_HAS_ARRAY_EXTRAS
|
||||
JS_FN("indexOf", array_indexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("lastIndexOf", array_lastIndexOf, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("forEach", array_forEach, 1,JSFUN_GENERIC_NATIVE),
|
||||
|
@ -2975,7 +2969,6 @@ static JSFunctionSpec array_methods[] = {
|
|||
JS_FN("filter", array_filter, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("some", array_some, 1,JSFUN_GENERIC_NATIVE),
|
||||
JS_FN("every", array_every, 1,JSFUN_GENERIC_NATIVE),
|
||||
#endif
|
||||
|
||||
JS_FS_END
|
||||
};
|
||||
|
@ -3026,19 +3019,33 @@ js_Array(JSContext *cx, uintN argc, Value *vp)
|
|||
JSObject *
|
||||
js_InitArrayClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto = js_InitClass(cx, obj, NULL, &js_ArrayClass, js_Array, 1,
|
||||
NULL, array_methods, NULL, array_static_methods);
|
||||
if (!proto)
|
||||
JS_ASSERT(obj->isNative());
|
||||
|
||||
GlobalObject *global = obj->asGlobal();
|
||||
|
||||
JSObject *arrayProto = global->createBlankPrototype(cx, &js_SlowArrayClass);
|
||||
if (!arrayProto || !AddLengthProperty(cx, arrayProto))
|
||||
return NULL;
|
||||
arrayProto->setArrayLength(0);
|
||||
|
||||
JSFunction *ctor = global->createConstructor(cx, js_Array, &js_ArrayClass,
|
||||
CLASS_ATOM(cx, Array), 1);
|
||||
if (!ctor)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Assert that js_InitClass used the correct (slow array, not dense array)
|
||||
* class for proto's emptyShape class.
|
||||
*/
|
||||
JS_ASSERT(proto->emptyShapes && proto->emptyShapes[0]->getClass() == proto->getClass());
|
||||
if (!LinkConstructorAndPrototype(cx, ctor, arrayProto))
|
||||
return NULL;
|
||||
|
||||
proto->setArrayLength(0);
|
||||
return proto;
|
||||
if (!DefinePropertiesAndBrand(cx, arrayProto, NULL, array_methods) ||
|
||||
!DefinePropertiesAndBrand(cx, ctor, NULL, array_static_methods))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!DefineConstructorAndPrototype(cx, global, JSProto_Array, ctor, arrayProto))
|
||||
return NULL;
|
||||
|
||||
return arrayProto;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -965,9 +965,6 @@ static JS_ALWAYS_INLINE JSScript *
|
|||
EvalCacheLookup(JSContext *cx, JSLinearString *str, StackFrame *caller, uintN staticLevel,
|
||||
JSPrincipals *principals, JSObject &scopeobj, JSScript **bucket)
|
||||
{
|
||||
if (!principals)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Cache local eval scripts indexed by source qualified by scope.
|
||||
*
|
||||
|
@ -995,7 +992,7 @@ EvalCacheLookup(JSContext *cx, JSLinearString *str, StackFrame *caller, uintN st
|
|||
script->getVersion() == version &&
|
||||
!script->hasSingletons &&
|
||||
(script->principals == principals ||
|
||||
(script->principals &&
|
||||
(principals && script->principals &&
|
||||
principals->subsume(principals, script->principals) &&
|
||||
script->principals->subsume(script->principals, principals)))) {
|
||||
/*
|
||||
|
@ -3780,15 +3777,21 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
|
|||
* (3) is not enough without addressing the bootstrapping dependency on (1)
|
||||
* and (2).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create the prototype object. (GlobalObject::createBlankPrototype isn't
|
||||
* used because it parents the prototype object to the global and because
|
||||
* it uses WithProto::Given. FIXME: Undo dependencies on this parentage
|
||||
* [which already needs to happen for bug 638316], figure out nicer
|
||||
* semantics for null-protoProto, and use createBlankPrototype.)
|
||||
*/
|
||||
JSObject *proto = NewObject<WithProto::Class>(cx, clasp, protoProto, obj);
|
||||
if (!proto)
|
||||
if (!proto || !proto->getEmptyShape(cx, proto->clasp, gc::FINALIZE_OBJECT0))
|
||||
return NULL;
|
||||
|
||||
proto->syncSpecialEquality();
|
||||
|
||||
/* After this point, control must exit via label bad or out. */
|
||||
AutoObjectRooter tvr(cx, proto);
|
||||
|
||||
JSObject *ctor;
|
||||
bool named = false;
|
||||
if (!constructor) {
|
||||
|
@ -3855,22 +3858,6 @@ DefineConstructorAndPrototype(JSContext *cx, JSObject *obj, JSProtoKey key, JSAt
|
|||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure proto's emptyShape is available to be shared by objects of
|
||||
* this class. JSObject::emptyShape is a one-slot cache. If we omit this,
|
||||
* some other class could snap it up. (The risk is particularly great for
|
||||
* Object.prototype.)
|
||||
*
|
||||
* All callers of JSObject::initSharingEmptyShape depend on this.
|
||||
*
|
||||
* FIXME: bug 592296 -- js_InitArrayClass should pass &js_SlowArrayClass
|
||||
* and make the Array.prototype slow from the start.
|
||||
*/
|
||||
JS_ASSERT_IF(proto->clasp != clasp,
|
||||
clasp == &js_ArrayClass && proto->clasp == &js_SlowArrayClass);
|
||||
if (!proto->getEmptyShape(cx, proto->clasp, FINALIZE_OBJECT0))
|
||||
goto bad;
|
||||
|
||||
if (clasp->flags & (JSCLASS_FREEZE_PROTO|JSCLASS_FREEZE_CTOR)) {
|
||||
JS_ASSERT_IF(ctor == proto, !(clasp->flags & JSCLASS_FREEZE_CTOR));
|
||||
if (proto && (clasp->flags & JSCLASS_FREEZE_PROTO) && !proto->freeze(cx))
|
||||
|
|
|
@ -1356,10 +1356,9 @@ CopyInitializerObject(JSContext *cx, JSObject *baseobj)
|
|||
}
|
||||
|
||||
inline bool
|
||||
DefineConstructorAndPrototype(JSContext *cx, JSObject *global,
|
||||
DefineConstructorAndPrototype(JSContext *cx, GlobalObject *global,
|
||||
JSProtoKey key, JSFunction *ctor, JSObject *proto)
|
||||
{
|
||||
JS_ASSERT(global->isGlobal());
|
||||
JS_ASSERT(!global->nativeEmpty()); /* reserved slots already allocated */
|
||||
JS_ASSERT(ctor);
|
||||
JS_ASSERT(proto);
|
||||
|
|
|
@ -243,10 +243,16 @@ class AutoScriptUntrapper {
|
|||
JSScript *script;
|
||||
jsbytecode *origPC;
|
||||
jsbytecode *newPC;
|
||||
#ifdef DEBUG
|
||||
bool assertionBefore;
|
||||
#endif
|
||||
|
||||
public:
|
||||
AutoScriptUntrapper(JSContext *cx, JSScript *script, jsbytecode **pc)
|
||||
: cx(cx), script(script), origPC(*pc)
|
||||
#ifdef DEBUG
|
||||
, assertionBefore(false)
|
||||
#endif
|
||||
{
|
||||
jsbytecode *newCode = js_UntrapScriptCode(cx, script);
|
||||
if (newCode == script->code) {
|
||||
|
@ -256,6 +262,10 @@ public:
|
|||
script->main += newCode - script->code;
|
||||
*pc = newPC = origPC + (newCode - script->code);
|
||||
script->code = newCode;
|
||||
#ifdef DEBUG
|
||||
assertionBefore = cx->stackIterAssertionEnabled;
|
||||
cx->stackIterAssertionEnabled = false;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
~AutoScriptUntrapper()
|
||||
|
@ -266,6 +276,9 @@ public:
|
|||
cx->free_(script->code);
|
||||
script->code = oldCode;
|
||||
script->main -= delta;
|
||||
#ifdef DEBUG
|
||||
cx->stackIterAssertionEnabled = assertionBefore;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -5601,32 +5601,29 @@ js_OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char)
|
|||
static uint32
|
||||
Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length)
|
||||
{
|
||||
uint32 ucs4Char;
|
||||
uint32 minucs4Char;
|
||||
/* from Unicode 3.1, non-shortest form is illegal */
|
||||
static const uint32 minucs4Table[] = {
|
||||
0x00000080, 0x00000800, 0x00010000
|
||||
};
|
||||
JS_ASSERT(1 <= utf8Length && utf8Length <= 4);
|
||||
|
||||
JS_ASSERT(utf8Length >= 1 && utf8Length <= 4);
|
||||
if (utf8Length == 1) {
|
||||
ucs4Char = *utf8Buffer;
|
||||
JS_ASSERT(!(ucs4Char & 0x80));
|
||||
} else {
|
||||
JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7-utf8Length)))) ==
|
||||
(0x100 - (1 << (8-utf8Length))));
|
||||
ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1);
|
||||
minucs4Char = minucs4Table[utf8Length-2];
|
||||
while (--utf8Length) {
|
||||
JS_ASSERT((*utf8Buffer & 0xC0) == 0x80);
|
||||
ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F);
|
||||
}
|
||||
if (JS_UNLIKELY(ucs4Char < minucs4Char || (ucs4Char >= 0xD800 && ucs4Char <= 0xDFFF))) {
|
||||
ucs4Char = INVALID_UTF8;
|
||||
} else if (ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) {
|
||||
ucs4Char = 0xFFFD;
|
||||
}
|
||||
JS_ASSERT(!(*utf8Buffer & 0x80));
|
||||
return *utf8Buffer;
|
||||
}
|
||||
|
||||
/* from Unicode 3.1, non-shortest form is illegal */
|
||||
static const uint32 minucs4Table[] = { 0x80, 0x800, 0x10000 };
|
||||
|
||||
JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7 - utf8Length)))) ==
|
||||
(0x100 - (1 << (8 - utf8Length))));
|
||||
uint32 ucs4Char = *utf8Buffer++ & ((1 << (7 - utf8Length)) - 1);
|
||||
uint32 minucs4Char = minucs4Table[utf8Length - 2];
|
||||
while (--utf8Length) {
|
||||
JS_ASSERT((*utf8Buffer & 0xC0) == 0x80);
|
||||
ucs4Char = (ucs4Char << 6) | (*utf8Buffer++ & 0x3F);
|
||||
}
|
||||
|
||||
if (JS_UNLIKELY(ucs4Char < minucs4Char || (ucs4Char >= 0xD800 && ucs4Char <= 0xDFFF)))
|
||||
ucs4Char = INVALID_UTF8;
|
||||
else if (ucs4Char == 0xFFFE || ucs4Char == 0xFFFF)
|
||||
ucs4Char = 0xFFFD;
|
||||
return ucs4Char;
|
||||
}
|
||||
|
||||
|
|
|
@ -15176,13 +15176,25 @@ TraceRecorder::record_JSOP_BINDNAME()
|
|||
if (!fp->isFunctionFrame()) {
|
||||
obj = &fp->scopeChain();
|
||||
|
||||
#ifdef DEBUG
|
||||
StackFrame *fp2 = fp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* In global code, fp->scopeChain can only contain blocks whose values
|
||||
* are still on the stack. We never use BINDNAME to refer to these.
|
||||
*/
|
||||
while (obj->isBlock()) {
|
||||
// The block's values are still on the stack.
|
||||
JS_ASSERT(obj->getPrivate() == fp);
|
||||
#ifdef DEBUG
|
||||
// NB: fp2 can't be a generator frame, because !fp->hasFunction.
|
||||
while (obj->getPrivate() != fp2) {
|
||||
JS_ASSERT(fp2->isEvalFrame());
|
||||
fp2 = fp2->prev();
|
||||
if (!fp2)
|
||||
JS_NOT_REACHED("bad stack frame");
|
||||
}
|
||||
#endif
|
||||
obj = obj->getParent();
|
||||
// Blocks always have parents.
|
||||
JS_ASSERT(obj);
|
||||
|
|
|
@ -96,7 +96,6 @@
|
|||
#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */
|
||||
#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */
|
||||
#define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support */
|
||||
#define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */
|
||||
#define JS_HAS_GENERATORS 0 /* has yield in generator function */
|
||||
#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */
|
||||
#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */
|
||||
|
@ -123,7 +122,6 @@
|
|||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */
|
||||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */
|
||||
#define JS_HAS_XML_SUPPORT 0 /* has ECMAScript for XML support */
|
||||
#define JS_HAS_ARRAY_EXTRAS 0 /* has indexOf and Lispy extras */
|
||||
#define JS_HAS_GENERATORS 0 /* has yield in generator function */
|
||||
#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */
|
||||
#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */
|
||||
|
@ -146,7 +144,6 @@
|
|||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */
|
||||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */
|
||||
#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support */
|
||||
#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */
|
||||
#define JS_HAS_GENERATORS 0 /* has yield in generator function */
|
||||
#define JS_HAS_BLOCK_SCOPE 0 /* has block scope via let/arraycomp */
|
||||
#define JS_HAS_DESTRUCTURING 0 /* has [a,b] = ... or {p:a,q:b} = ... */
|
||||
|
@ -169,7 +166,6 @@
|
|||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */
|
||||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */
|
||||
#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support */
|
||||
#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */
|
||||
#define JS_HAS_GENERATORS 1 /* has yield in generator function */
|
||||
#define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycomp */
|
||||
#define JS_HAS_DESTRUCTURING 1 /* has [a,b] = ... or {p:a,q:b} = ... */
|
||||
|
@ -192,7 +188,6 @@
|
|||
#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */
|
||||
#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */
|
||||
#define JS_HAS_XML_SUPPORT 1 /* has ECMAScript for XML support */
|
||||
#define JS_HAS_ARRAY_EXTRAS 1 /* has indexOf and Lispy extras */
|
||||
#define JS_HAS_GENERATORS 1 /* has yield in generator function */
|
||||
#define JS_HAS_BLOCK_SCOPE 1 /* has block scope via let/arraycomp */
|
||||
#define JS_HAS_DESTRUCTURING 2 /* has [a,b] = ... or {p:a,q:b} = ... */
|
||||
|
|
|
@ -508,7 +508,8 @@ NewXMLAttributeName(JSContext *cx, JSLinearString *uri, JSLinearString *prefix,
|
|||
* AttributeName is an internal anonymous class which instances are not
|
||||
* exposed to scripts.
|
||||
*/
|
||||
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AttributeNameClass, NULL, NULL);
|
||||
JSObject *parent = GetGlobalForScopeChain(cx);
|
||||
JSObject *obj = NewNonFunction<WithProto::Given>(cx, &js_AttributeNameClass, NULL, parent);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
JS_ASSERT(obj->isQName());
|
||||
|
@ -7072,7 +7073,8 @@ NewXMLObject(JSContext *cx, JSXML *xml)
|
|||
{
|
||||
JSObject *obj;
|
||||
|
||||
obj = NewNonFunction<WithProto::Class>(cx, &js_XMLClass, NULL, NULL);
|
||||
JSObject *parent = GetGlobalForScopeChain(cx);
|
||||
obj = NewNonFunction<WithProto::Class>(cx, &js_XMLClass, NULL, parent);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
obj->setPrivate(xml);
|
||||
|
@ -7616,7 +7618,8 @@ js_StepXMLListFilter(JSContext *cx, JSBool initialized)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
filterobj = NewNonFunction<WithProto::Given>(cx, &js_XMLFilterClass, NULL, NULL);
|
||||
JSObject *parent = GetGlobalForScopeChain(cx);
|
||||
filterobj = NewNonFunction<WithProto::Given>(cx, &js_XMLFilterClass, NULL, parent);
|
||||
if (!filterobj)
|
||||
return JS_FALSE;
|
||||
|
||||
|
|
|
@ -392,6 +392,34 @@ SetContextOptions(JSContext *cx)
|
|||
JS_SetOperationCallback(cx, ShellOperationCallback);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some UTF-8 files, notably those written using Notepad, have a Unicode
|
||||
* Byte-Order-Mark (BOM) as their first character. This is useless (byte-order
|
||||
* is meaningless for UTF-8) but causes a syntax error unless we skip it.
|
||||
*/
|
||||
static void
|
||||
SkipUTF8BOM(FILE* file)
|
||||
{
|
||||
if (!js_CStringsAreUTF8)
|
||||
return;
|
||||
|
||||
int ch1 = fgetc(file);
|
||||
int ch2 = fgetc(file);
|
||||
int ch3 = fgetc(file);
|
||||
|
||||
// Skip the BOM
|
||||
if (ch1 == 0xEF && ch2 == 0xBB && ch3 == 0xBF)
|
||||
return;
|
||||
|
||||
// No BOM - revert
|
||||
if (ch3 != EOF)
|
||||
ungetc(ch3, file);
|
||||
if (ch2 != EOF)
|
||||
ungetc(ch2, file);
|
||||
if (ch1 != EOF)
|
||||
ungetc(ch1, file);
|
||||
}
|
||||
|
||||
static void
|
||||
Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
|
||||
{
|
||||
|
@ -424,6 +452,8 @@ Process(JSContext *cx, JSObject *obj, char *filename, JSBool forceTTY)
|
|||
|
||||
if (!forceTTY && !isatty(fileno(file)))
|
||||
{
|
||||
SkipUTF8BOM(file);
|
||||
|
||||
/*
|
||||
* It's not interactive - just execute it.
|
||||
*
|
||||
|
|
|
@ -1750,6 +1750,10 @@ FindObjectPrincipals(JSContext *cx, JSObject *obj)
|
|||
return gJSPrincipals;
|
||||
}
|
||||
|
||||
// defined in nsScriptSecurityManager.cpp
|
||||
NS_IMPORT JSPrincipals *
|
||||
NS_DefaultObjectPrincipalFinder(JSContext *cx, JSObject *obj);
|
||||
|
||||
int
|
||||
main(int argc, char **argv, char **envp)
|
||||
{
|
||||
|
@ -1903,7 +1907,7 @@ main(int argc, char **argv, char **envp)
|
|||
|
||||
JSSecurityCallbacks *cb = JS_GetRuntimeSecurityCallbacks(rt);
|
||||
NS_ASSERTION(cb, "We are assuming that nsScriptSecurityManager::Init() has been run");
|
||||
NS_ASSERTION(!cb->findObjectPrincipals, "Your pigeon is in my hole!");
|
||||
NS_ASSERTION(cb->findObjectPrincipals == NS_DefaultObjectPrincipalFinder, "Your pigeon is in my hole!");
|
||||
cb->findObjectPrincipals = FindObjectPrincipals;
|
||||
|
||||
#ifdef TEST_TranslateThis
|
||||
|
|
|
@ -1057,7 +1057,7 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
|||
oldContext->AddRef();
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
PRBool wasFrameVisible = mPresShell->IsAccessibilityActive() ?
|
||||
PRBool wasFrameVisible = nsIPresShell::IsAccessibilityActive() ?
|
||||
oldContext->GetStyleVisibility()->IsVisible() : PR_FALSE;
|
||||
#endif
|
||||
|
||||
|
@ -1429,7 +1429,8 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
|
|||
// Notify a11y for primary frame only if it's a root frame of visibility
|
||||
// changes or its parent frame was hidden while it stays visible and
|
||||
// it is not inside a {ib} split or is the first frame of {ib} split.
|
||||
if (mPresShell->IsAccessibilityActive() && !aFrame->GetPrevContinuation() &&
|
||||
if (nsIPresShell::IsAccessibilityActive() &&
|
||||
!aFrame->GetPrevContinuation() &&
|
||||
!nsLayoutUtils::FrameIsNonFirstInIBSplit(aFrame)) {
|
||||
if (aDesiredA11yNotifications == eSendAllNotifications) {
|
||||
PRBool isFrameVisible = newContext->GetStyleVisibility()->IsVisible();
|
||||
|
|
|
@ -821,10 +821,12 @@ public:
|
|||
virtual void VerifyStyleTree() = 0;
|
||||
#endif
|
||||
|
||||
static PRBool gIsAccessibilityActive;
|
||||
static PRBool IsAccessibilityActive() { return gIsAccessibilityActive; }
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
/**
|
||||
* Return true if accessibility is active.
|
||||
*/
|
||||
static bool IsAccessibilityActive();
|
||||
|
||||
/**
|
||||
* Return accessibility service if accessibility is active.
|
||||
*/
|
||||
|
|
|
@ -236,7 +236,6 @@ using namespace mozilla;
|
|||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
PRBool nsIPresShell::gIsAccessibilityActive = PR_FALSE;
|
||||
CapturingContentInfo nsIPresShell::gCaptureInfo =
|
||||
{ PR_FALSE /* mAllowed */, PR_FALSE /* mRetargetToElement */,
|
||||
PR_FALSE /* mPreventDrag */, nsnull /* mContent */ };
|
||||
|
@ -1844,9 +1843,6 @@ PresShell::Init(nsIDocument* aDocument,
|
|||
os->AddObserver(this, "user-sheet-removed", PR_FALSE);
|
||||
#ifdef MOZ_XUL
|
||||
os->AddObserver(this, "chrome-flush-skin-caches", PR_FALSE);
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
os->AddObserver(this, "a11y-init-or-shutdown", PR_FALSE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -1933,9 +1929,6 @@ PresShell::Destroy()
|
|||
os->RemoveObserver(this, "user-sheet-removed");
|
||||
#ifdef MOZ_XUL
|
||||
os->RemoveObserver(this, "chrome-flush-skin-caches");
|
||||
#endif
|
||||
#ifdef ACCESSIBILITY
|
||||
os->RemoveObserver(this, "a11y-init-or-shutdown");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -6983,9 +6976,6 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
|
|||
accEvent->mAccessible =
|
||||
accService->GetRootDocumentAccessible(this, nsContentUtils::IsSafeToRunScript());
|
||||
|
||||
// Ensure this is set in case a11y was activated before any
|
||||
// nsPresShells existed to observe "a11y-init-or-shutdown" topic
|
||||
gIsAccessibilityActive = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
@ -8232,12 +8222,6 @@ PresShell::Observe(nsISupports* aSubject,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
if (!nsCRT::strcmp(aTopic, "a11y-init-or-shutdown")) {
|
||||
gIsAccessibilityActive = aData && *aData == '1';
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
NS_WARNING("unrecognized topic in PresShell::Observe");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -9328,6 +9312,12 @@ nsIFrame* nsIPresShell::GetAbsoluteContainingBlock(nsIFrame *aFrame)
|
|||
}
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
bool
|
||||
nsIPresShell::IsAccessibilityActive()
|
||||
{
|
||||
return GetAccService() != nsnull;
|
||||
}
|
||||
|
||||
nsAccessibilityService*
|
||||
nsIPresShell::AccService()
|
||||
{
|
||||
|
|
|
@ -382,6 +382,9 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
|||
return;
|
||||
const FrameMetrics metrics = container->GetFrameMetrics();
|
||||
const ViewID scrollId = metrics.mScrollId;
|
||||
const gfx3DMatrix transform = aLayer->GetTransform();
|
||||
aXScale *= GetXScale(transform);
|
||||
aYScale *= GetYScale(transform);
|
||||
|
||||
if (metrics.IsScrollable()) {
|
||||
nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent()
|
||||
|
@ -393,7 +396,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
|||
ViewConfig config = view->GetViewConfig();
|
||||
aXScale *= config.mXScale;
|
||||
aYScale *= config.mYScale;
|
||||
view->mOwnerContent = aFrameLoader->GetOwnerContent();
|
||||
view->mFrameLoader = aFrameLoader;
|
||||
} else {
|
||||
// View doesn't exist, so generate one. We start the view scroll offset at
|
||||
// the same position as the framemetric's scroll offset from the layer.
|
||||
|
@ -402,7 +405,7 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
|||
config.mScrollOffset = nsPoint(
|
||||
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.x, auPerDevPixel) * aXScale,
|
||||
NSIntPixelsToAppUnits(metrics.mViewportScrollOffset.y, auPerDevPixel) * aYScale);
|
||||
view = new nsContentView(aFrameLoader->GetOwnerContent(), scrollId, config);
|
||||
view = new nsContentView(aFrameLoader, scrollId, config);
|
||||
}
|
||||
|
||||
view->mViewportSize = nsSize(
|
||||
|
@ -417,9 +420,6 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
|||
|
||||
for (Layer* child = aLayer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
const gfx3DMatrix transform = aLayer->GetTransform();
|
||||
aXScale *= GetXScale(transform);
|
||||
aYScale *= GetYScale(transform);
|
||||
BuildViewMap(oldContentViews, newContentViews, aFrameLoader, child,
|
||||
aXScale, aYScale);
|
||||
}
|
||||
|
@ -558,7 +558,7 @@ BuildBackgroundPatternFor(ContainerLayer* aContainer,
|
|||
bgRgn.Sub(bgRgn, localIntContentVis);
|
||||
bgRgn.MoveBy(-translation);
|
||||
layer->SetVisibleRegion(bgRgn);
|
||||
|
||||
|
||||
aContainer->InsertAfter(layer, nsnull);
|
||||
}
|
||||
|
||||
|
@ -567,8 +567,7 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader)
|
|||
{
|
||||
NS_ABORT_IF_FALSE(aFrameLoader, "Need a frameloader here");
|
||||
mContentViews[FrameMetrics::ROOT_SCROLL_ID] =
|
||||
new nsContentView(aFrameLoader->GetOwnerContent(),
|
||||
FrameMetrics::ROOT_SCROLL_ID);
|
||||
new nsContentView(aFrameLoader, FrameMetrics::ROOT_SCROLL_ID);
|
||||
}
|
||||
|
||||
RenderFrameParent::~RenderFrameParent()
|
||||
|
@ -594,6 +593,14 @@ RenderFrameParent::GetContentView(ViewID aId)
|
|||
return FindViewForId(mContentViews, aId);
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::ContentViewScaleChanged(nsContentView* aView)
|
||||
{
|
||||
// Since the scale has changed for a view, it and its descendents need their
|
||||
// shadow-space attributes updated. It's easiest to rebuild the view map.
|
||||
BuildViewMap();
|
||||
}
|
||||
|
||||
void
|
||||
RenderFrameParent::ShadowLayersUpdated()
|
||||
{
|
||||
|
@ -756,13 +763,13 @@ RenderFrameParent::BuildViewMap()
|
|||
// tag them as inactive and to remove any chance of them using a dangling
|
||||
// pointer, we set mContentView to NULL.
|
||||
//
|
||||
// BuildViewMap will restore mOwnerContent if the content view is still
|
||||
// BuildViewMap will restore mFrameLoader if the content view is still
|
||||
// in our hash table.
|
||||
|
||||
for (ViewMap::const_iterator iter = mContentViews.begin();
|
||||
iter != mContentViews.end();
|
||||
++iter) {
|
||||
iter->second->mOwnerContent = NULL;
|
||||
iter->second->mFrameLoader = NULL;
|
||||
}
|
||||
|
||||
mozilla::layout::BuildViewMap(mContentViews, newContentViews, mFrameLoader, GetRootLayer());
|
||||
|
@ -776,7 +783,7 @@ RenderFrameParent::BuildViewMap()
|
|||
newContentViews[FrameMetrics::ROOT_SCROLL_ID] =
|
||||
FindViewForId(mContentViews, FrameMetrics::ROOT_SCROLL_ID);
|
||||
}
|
||||
|
||||
|
||||
mContentViews = newContentViews;
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,8 @@ public:
|
|||
*/
|
||||
nsContentView* GetContentView(ViewID aId = FrameMetrics::ROOT_SCROLL_ID);
|
||||
|
||||
void ContentViewScaleChanged(nsContentView* aView);
|
||||
|
||||
void ShadowLayersUpdated();
|
||||
|
||||
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
|
|
|
@ -17,7 +17,7 @@ HTTP(..) != font-features-hlig.html font-features-ref.html
|
|||
|
||||
# compare Turkish rendering with reference using ZWNJ to break the ligature
|
||||
# (also works via Pango)
|
||||
fails-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)) HTTP(..) == font-features-turkish.html font-features-turkish-ref.html
|
||||
fails-if(d2d) HTTP(..) == font-features-turkish.html font-features-turkish-ref.html
|
||||
|
||||
# compare Turkish rendering with explicitly disabled ligatures
|
||||
HTTP(..) == font-features-turkish.html font-features-noliga.html
|
||||
|
|
|
@ -4,7 +4,7 @@ reftest.jar:
|
|||
* content/reftest.js (reftest.js)
|
||||
content/reftest-content.js (reftest-content.js)
|
||||
content/reftest.xul (reftest.xul)
|
||||
content/MozillaFileLogger.js (../../../testing/mochitest/tests/SimpleTest/MozillaFileLogger.js)
|
||||
content/MozillaLogger.js (../../../testing/mochitest/tests/SimpleTest/MozillaLogger.js)
|
||||
#ifdef XPI_NAME
|
||||
% component {32530271-8c1b-4b7d-a812-218e42c6bb23} components/reftest-cmdline.js
|
||||
% contract @mozilla.org/commandlinehandler/general-startup;1?type=reftest {32530271-8c1b-4b7d-a812-218e42c6bb23}
|
||||
|
|
|
@ -264,9 +264,9 @@ function InitAndStartRefTests()
|
|||
logFile = prefs.getCharPref("reftest.logFile");
|
||||
if (logFile) {
|
||||
try {
|
||||
MozillaFileLogger.init(logFile);
|
||||
var mfl = new MozillaFileLogger(logFile);
|
||||
// Set to mirror to stdout as well as the file
|
||||
gDumpLog = function (msg) {dump(msg); MozillaFileLogger.log(msg);};
|
||||
gDumpLog = function (msg) {dump(msg); mfl.log(msg);};
|
||||
}
|
||||
catch(e) {
|
||||
// If there is a problem, just use stdout
|
||||
|
|
|
@ -51,6 +51,6 @@
|
|||
>
|
||||
<script type="application/ecmascript" src="quit.js" />
|
||||
<script type="application/ecmascript" src="reftest.js" />
|
||||
<script type="application/ecmascript" src="MozillaFileLogger.js" />
|
||||
<script type="application/ecmascript" src="MozillaLogger.js" />
|
||||
<!-- The reftest browser element is dynamically created, here -->
|
||||
</window>
|
||||
|
|
|
@ -1267,13 +1267,14 @@ nsListBoxBodyFrame::GetNextItemBox(nsIBox* aBox, PRInt32 aOffset,
|
|||
|
||||
PRBool
|
||||
nsListBoxBodyFrame::ContinueReflow(nscoord height)
|
||||
{
|
||||
nsPresContext* presContext = PresContext();
|
||||
if (presContext->PresShell()->IsAccessibilityActive()) {
|
||||
{
|
||||
#ifdef ACCESSIBILITY
|
||||
if (nsIPresShell::IsAccessibilityActive()) {
|
||||
// Create all the frames at once so screen readers and
|
||||
// onscreen keyboards can see the full list right away
|
||||
return PR_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (height <= 0) {
|
||||
nsIFrame* lastChild = GetLastFrame();
|
||||
|
|
|
@ -683,8 +683,7 @@ nsTreeBodyFrame::InvalidateColumn(nsITreeColumn* aCol)
|
|||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive())
|
||||
if (nsIPresShell::IsAccessibilityActive())
|
||||
FireInvalidateEvent(-1, -1, aCol, aCol);
|
||||
#endif
|
||||
|
||||
|
@ -706,8 +705,7 @@ nsTreeBodyFrame::InvalidateRow(PRInt32 aIndex)
|
|||
return NS_OK;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive())
|
||||
if (nsIPresShell::IsAccessibilityActive())
|
||||
FireInvalidateEvent(aIndex, aIndex, nsnull, nsnull);
|
||||
#endif
|
||||
|
||||
|
@ -728,8 +726,7 @@ nsTreeBodyFrame::InvalidateCell(PRInt32 aIndex, nsITreeColumn* aCol)
|
|||
return NS_OK;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive())
|
||||
if (nsIPresShell::IsAccessibilityActive())
|
||||
FireInvalidateEvent(aIndex, aIndex, aCol, aCol);
|
||||
#endif
|
||||
|
||||
|
@ -772,8 +769,7 @@ nsTreeBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
|
|||
aEnd = last;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive()) {
|
||||
if (nsIPresShell::IsAccessibilityActive()) {
|
||||
PRInt32 end =
|
||||
mRowCount > 0 ? ((mRowCount <= aEnd) ? mRowCount - 1 : aEnd) : 0;
|
||||
FireInvalidateEvent(aStart, end, nsnull, nsnull);
|
||||
|
@ -810,8 +806,7 @@ nsTreeBodyFrame::InvalidateColumnRange(PRInt32 aStart, PRInt32 aEnd, nsITreeColu
|
|||
aEnd = last;
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive()) {
|
||||
if (nsIPresShell::IsAccessibilityActive()) {
|
||||
PRInt32 end =
|
||||
mRowCount > 0 ? ((mRowCount <= aEnd) ? mRowCount - 1 : aEnd) : 0;
|
||||
FireInvalidateEvent(aStart, end, aCol, aCol);
|
||||
|
@ -1822,8 +1817,7 @@ nsTreeBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCount)
|
|||
return NS_OK; // Nothing to do.
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
nsIPresShell *presShell = PresContext()->PresShell();
|
||||
if (presShell->IsAccessibilityActive())
|
||||
if (nsIPresShell::IsAccessibilityActive())
|
||||
FireRowCountChangedEvent(aIndex, aCount);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -64,6 +64,11 @@ var ContextCommands = {
|
|||
null, browser.documentURI, true, null);
|
||||
},
|
||||
|
||||
copyLink: function cc_copyLink() {
|
||||
let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
|
||||
clipboard.copyString(ContextHelper.popupState.linkURL);
|
||||
},
|
||||
|
||||
shareLink: function cc_shareLink() {
|
||||
let state = ContextHelper.popupState;
|
||||
SharingUI.show(state.linkURL, state.linkTitle);
|
||||
|
|
|
@ -23,7 +23,7 @@ var OfflineApps = {
|
|||
|
||||
let host = currentURI.asciiHost;
|
||||
let notificationID = "offline-app-requested-" + host;
|
||||
let notificationBox = Browser.getNotificationBox();
|
||||
let notificationBox = Browser.getNotificationBox(aTarget);
|
||||
|
||||
let notification = notificationBox.getNotificationWithValue(notificationID);
|
||||
let strings = Strings.browser;
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* William Price <bugzilla@mob.rice.edu>
|
||||
* Steven Garrity <steven@silverorange.com>
|
||||
* Henrik Skupin <mozilla@hskupin.info>
|
||||
* Johnathan Nightingale <johnath@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/* Logical CSS rules belong here, but presentation & theming rules
|
||||
should live in the CSS of the appropriate theme */
|
||||
|
||||
#technicalContentText {
|
||||
overflow: auto;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
#technicalContent > h2, #expertContent > h2 {
|
||||
cursor: pointer;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
left: -20px;
|
||||
}
|
||||
|
||||
div[collapsed] > p,
|
||||
div[collapsed] > div {
|
||||
display: none;
|
||||
}
|
|
@ -57,8 +57,8 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>&certerror.pagetitle;</title>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/aboutCertError.css" type="text/css" media="all" />
|
||||
<link rel="stylesheet" href="chrome://browser/content/aboutCertError.css" type="text/css" media="all" />
|
||||
<meta name="viewport" content="width=device-width; user-scalable=false" />
|
||||
<link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
|
||||
<!-- This page currently uses the same favicon as neterror.xhtml.
|
||||
If the location of the favicon is changed for both pages, the
|
||||
FAVICON_ERRORPAGE_URL symbol in toolkit/components/places/src/nsFaviconService.h
|
||||
|
@ -218,28 +218,27 @@
|
|||
function toggle(id) {
|
||||
var el = document.getElementById(id);
|
||||
if (el.getAttribute("collapsed"))
|
||||
el.removeAttribute("collapsed");
|
||||
el.setAttribute("collapsed", false);
|
||||
else
|
||||
el.setAttribute("collapsed", true);
|
||||
}
|
||||
]]></script>
|
||||
</head>
|
||||
|
||||
<body dir="&locale.dir;">
|
||||
<body id="errorPage" class="certerror" dir="&locale.dir;">
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 class="errorTitleText">&certerror.longpagetitle;</h1>
|
||||
</div>
|
||||
|
||||
<!-- PAGE CONTAINER (for styling purposes only) -->
|
||||
<div id="errorPageContainer">
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 id="errorTitleText">&certerror.longpagetitle;</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- LONG CONTENT (the section most likely to require scrolling) -->
|
||||
<div id="errorLongContent">
|
||||
<div id="introContent">
|
||||
<p id="introContentP1">&certerror.introPara1;</p>
|
||||
<p>&certerror.introPara2;</p>
|
||||
</div>
|
||||
|
||||
<div id="whatShouldIDoContent">
|
||||
|
|
|
@ -1309,7 +1309,12 @@
|
|||
let lastTitle = null;
|
||||
let msPerDay = 86400000;
|
||||
let msPerWeek = msPerDay * 7;
|
||||
let today = new Date(Date.now() - (Date.now() % msPerDay));
|
||||
|
||||
let today = new Date();
|
||||
today.setHours(0);
|
||||
today.setMinutes(0);
|
||||
today.setSeconds(0);
|
||||
|
||||
for (let i = 0; i < childCount; i++) {
|
||||
let node = rootNode.getChild(i);
|
||||
let time = new Date(node.time / 1000); // node.time is microseconds
|
||||
|
|
|
@ -918,16 +918,8 @@
|
|||
|
||||
_getContentSize: function() {
|
||||
let self = this.self;
|
||||
if (this.isRoot()) {
|
||||
// XXX Bug 626792 means contentWidth and contentHeight aren't always
|
||||
// updated immediately. This makes the displayport go haywire so
|
||||
// use contentDocument properties.
|
||||
return { width: self._contentDocumentWidth * this._scale,
|
||||
height: self._contentDocumentHeight * this._scale };
|
||||
} else {
|
||||
return { width: this._contentView.contentWidth,
|
||||
height: this._contentView.contentHeight };
|
||||
}
|
||||
return { width: this._contentView.contentWidth,
|
||||
height: this._contentView.contentHeight };
|
||||
},
|
||||
|
||||
_getViewportSize: function() {
|
||||
|
@ -936,7 +928,8 @@
|
|||
let bcr = self.getBoundingClientRect();
|
||||
return { width: bcr.width, height: bcr.height };
|
||||
} else {
|
||||
return { width: this._contentView.viewportWidth, height: this._contentView.viewportHeight };
|
||||
return { width: this._contentView.viewportWidth,
|
||||
height: this._contentView.viewportHeight };
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="blacklist">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width; user-scalable=false" />
|
||||
<link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
|
||||
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/blacklist_favicon.png"/>
|
||||
|
||||
|
@ -186,26 +187,27 @@
|
|||
</style>
|
||||
</head>
|
||||
|
||||
<body dir="&locale.dir;">
|
||||
<body id="errorPage" class="blockedsite" dir="&locale.dir;">
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 id="errorTitleText_phishing" class="errorTitleText">&safeb.blocked.phishingPage.title2;</h1>
|
||||
<h1 id="errorTitleText_malware" class="errorTitleText">&safeb.blocked.malwarePage.title;</h1>
|
||||
</div>
|
||||
|
||||
<div id="errorPageContainer">
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 id="errorTitleText_phishing">&safeb.blocked.phishingPage.title;</h1>
|
||||
<h1 id="errorTitleText_malware">&safeb.blocked.malwarePage.title;</h1>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="errorLongContent">
|
||||
|
||||
<!-- Short Description -->
|
||||
<div id="errorShortDesc">
|
||||
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc;</p>
|
||||
<p id="errorShortDescText_phishing">&safeb.blocked.phishingPage.shortDesc2;</p>
|
||||
<p id="errorShortDescText_malware">&safeb.blocked.malwarePage.shortDesc;</p>
|
||||
</div>
|
||||
|
||||
<!-- Long Description -->
|
||||
<div id="errorLongDesc">
|
||||
<p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc;</p>
|
||||
<p id="errorLongDescText_phishing">&safeb.blocked.phishingPage.longDesc2;</p>
|
||||
<p id="errorLongDescText_malware">&safeb.blocked.malwarePage.longDesc;</p>
|
||||
</div>
|
||||
|
||||
|
@ -216,9 +218,6 @@
|
|||
<button id="reportButton">&safeb.palm.reportPage.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="ignoreWarning">
|
||||
<button id="ignoreWarningButton">&safeb.palm.decline.label;</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
- Note: It is important to run the script this way, instead of using
|
||||
|
|
|
@ -627,6 +627,9 @@
|
|||
<richlistitem class="context-command" id="context-saveimage" type="image-loaded" onclick="ContextCommands.saveImage();">
|
||||
<label value="&contextSaveImage.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-copy-link" type="link" onclick="ContextCommands.copyLink();">
|
||||
<label value="&contextCopyLink.label;"/>
|
||||
</richlistitem>
|
||||
<richlistitem class="context-command" id="context-share-link" type="link-shareable" onclick="ContextCommands.shareLink();">
|
||||
<label value="&contextShareLink.label;"/>
|
||||
</richlistitem>
|
||||
|
|
|
@ -1253,7 +1253,7 @@ var SelectionHelper = {
|
|||
return this._end = document.getElementById("selectionhandle-end");
|
||||
},
|
||||
|
||||
showPopup: function ch_showPopup(aMessage) {
|
||||
showPopup: function sh_showPopup(aMessage) {
|
||||
if (!this.enabled || aMessage.json.types.indexOf("content-text") == -1)
|
||||
return false;
|
||||
|
||||
|
@ -1302,11 +1302,16 @@ var SelectionHelper = {
|
|||
return true;
|
||||
},
|
||||
|
||||
hide: function ch_hide() {
|
||||
hide: function sh_hide() {
|
||||
if (this._start.hidden)
|
||||
return;
|
||||
|
||||
this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionEnd", {});
|
||||
try {
|
||||
this.popupState.target.messageManager.sendAsyncMessage("Browser:SelectionEnd", {});
|
||||
} catch (e) {
|
||||
Cu.reportError(e);
|
||||
}
|
||||
|
||||
this.popupState = null;
|
||||
Services.prefs.setBoolPref("accessibility.browsewithcaret", false);
|
||||
|
||||
|
|
|
@ -0,0 +1,400 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE html [
|
||||
<!ENTITY % htmlDTD
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"DTD/xhtml1-strict.dtd">
|
||||
%htmlDTD;
|
||||
<!ENTITY % netErrorDTD
|
||||
SYSTEM "chrome://global/locale/netError.dtd">
|
||||
%netErrorDTD;
|
||||
<!ENTITY % globalDTD
|
||||
SYSTEM "chrome://global/locale/global.dtd">
|
||||
%globalDTD;
|
||||
]>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is netError.xhtml.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 1998
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Wesley Johnston <wjohnston@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width; user-scalable=false;" />
|
||||
<title>&loadError.label;</title>
|
||||
<link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
|
||||
<!-- If the location of the favicon is changed here, the FAVICON_ERRORPAGE_URL symbol in
|
||||
toolkit/components/places/src/nsFaviconService.h should be updated. -->
|
||||
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/warning-16.png"/>
|
||||
|
||||
<script type="application/javascript"><![CDATA[
|
||||
// Error url MUST be formatted like this:
|
||||
// moz-neterror:page?e=error&u=url&d=desc
|
||||
//
|
||||
// or optionally, to specify an alternate CSS class to allow for
|
||||
// custom styling and favicon:
|
||||
//
|
||||
// moz-neterror:page?e=error&u=url&s=classname&d=desc
|
||||
|
||||
// Note that this file uses document.documentURI to get
|
||||
// the URL (with the format from above). This is because
|
||||
// document.location.href gets the current URI off the docshell,
|
||||
// which is the URL displayed in the location bar, i.e.
|
||||
// the URI that the user attempted to load.
|
||||
|
||||
function getErrorCode()
|
||||
{
|
||||
var url = document.documentURI;
|
||||
var error = url.search(/e\=/);
|
||||
var duffUrl = url.search(/\&u\=/);
|
||||
return decodeURIComponent(url.slice(error + 2, duffUrl));
|
||||
}
|
||||
|
||||
function getCSSClass()
|
||||
{
|
||||
var url = document.documentURI;
|
||||
var matches = url.match(/s\=([^&]+)\&/);
|
||||
// s is optional, if no match just return nothing
|
||||
if (!matches || matches.length < 2)
|
||||
return "";
|
||||
|
||||
// parenthetical match is the second entry
|
||||
return decodeURIComponent(matches[1]);
|
||||
}
|
||||
|
||||
function getDescription()
|
||||
{
|
||||
var url = document.documentURI;
|
||||
var desc = url.search(/d\=/);
|
||||
|
||||
// desc == -1 if not found; if so, return an empty string
|
||||
// instead of what would turn out to be portions of the URI
|
||||
if (desc == -1)
|
||||
return "";
|
||||
|
||||
return decodeURIComponent(url.slice(desc + 2));
|
||||
}
|
||||
|
||||
function retryThis(buttonEl)
|
||||
{
|
||||
// If this is the "Offline mode" page, go online!
|
||||
if (getErrorCode() == "netOffline") {
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIDOMWindowUtils)
|
||||
.goOnline();
|
||||
}
|
||||
|
||||
// Session history has the URL of the page that failed
|
||||
// to load, not the one of the error page. So, just call
|
||||
// reload(), which will also repost POST data correctly.
|
||||
try {
|
||||
location.reload();
|
||||
} catch (e) {
|
||||
// We probably tried to reload a URI that caused an exception to
|
||||
// occur; e.g. a nonexistent file.
|
||||
}
|
||||
|
||||
buttonEl.disabled = true;
|
||||
}
|
||||
|
||||
function initPage()
|
||||
{
|
||||
var err = getErrorCode();
|
||||
|
||||
// if it's an unknown error or there's no title or description
|
||||
// defined, get the generic message
|
||||
var errTitle = document.getElementById("et_" + err);
|
||||
var errDesc = document.getElementById("ed_" + err);
|
||||
if (!errTitle || !errDesc)
|
||||
{
|
||||
errTitle = document.getElementById("et_generic");
|
||||
errDesc = document.getElementById("ed_generic");
|
||||
}
|
||||
|
||||
var title = document.getElementsByClassName("errorTitleText")[0];
|
||||
if (title)
|
||||
{
|
||||
title.parentNode.replaceChild(errTitle, title);
|
||||
// change id to the replaced child's id so styling works
|
||||
errTitle.classList.add("errorTitleText");
|
||||
}
|
||||
|
||||
var sd = document.getElementById("errorShortDescText");
|
||||
if (sd)
|
||||
sd.textContent = getDescription();
|
||||
|
||||
var ld = document.getElementById("errorLongDesc");
|
||||
if (ld)
|
||||
{
|
||||
ld.parentNode.replaceChild(errDesc, ld);
|
||||
// change id to the replaced child's id so styling works
|
||||
errDesc.id = "errorLongDesc";
|
||||
}
|
||||
|
||||
// remove undisplayed errors to avoid bug 39098
|
||||
var errContainer = document.getElementById("errorContainer");
|
||||
errContainer.parentNode.removeChild(errContainer);
|
||||
|
||||
var className = getCSSClass();
|
||||
if (className && className != "expertBadCert") {
|
||||
// Associate a CSS class with the root of the page, if one was passed in,
|
||||
// to allow custom styling.
|
||||
// Not "expertBadCert" though, don't want to deal with the favicon
|
||||
document.documentElement.className = className;
|
||||
|
||||
// Also, if they specified a CSS class, they must supply their own
|
||||
// favicon. In order to trigger the browser to repaint though, we
|
||||
// need to remove/add the link element.
|
||||
var favicon = document.getElementById("favicon");
|
||||
var faviconParent = favicon.parentNode;
|
||||
faviconParent.removeChild(favicon);
|
||||
favicon.setAttribute("href", "chrome://global/skin/icons/" + className + "_favicon.png");
|
||||
faviconParent.appendChild(favicon);
|
||||
}
|
||||
if (className == "expertBadCert") {
|
||||
showSecuritySection();
|
||||
}
|
||||
|
||||
if (err == "remoteXUL") {
|
||||
// Remove the "Try again" button for remote XUL errors given that
|
||||
// it is useless.
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
||||
if (err == "cspFrameAncestorBlocked") {
|
||||
// Remove the "Try again" button for CSP frame ancestors violation, since it's
|
||||
// almost certainly useless. (Bug 553180)
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
||||
if (err == "nssBadCert") {
|
||||
// Remove the "Try again" button for security exceptions, since it's
|
||||
// almost certainly useless.
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
document.getElementById("errorPage").setAttribute("class", "certerror");
|
||||
addDomainErrorLink();
|
||||
}
|
||||
else {
|
||||
// Remove the override block for non-certificate errors. CSS-hiding
|
||||
// isn't good enough here, because of bug 39098
|
||||
var secOverride = document.getElementById("securityOverrideDiv");
|
||||
secOverride.parentNode.removeChild(secOverride);
|
||||
}
|
||||
}
|
||||
|
||||
function showSecuritySection() {
|
||||
// Swap link out, content in
|
||||
document.getElementById('securityOverrideContent').style.display = '';
|
||||
document.getElementById('securityOverrideLink').style.display = 'none';
|
||||
}
|
||||
|
||||
/* In the case of SSL error pages about domain mismatch, see if
|
||||
we can hyperlink the user to the correct site. We don't want
|
||||
to do this generically since it allows MitM attacks to redirect
|
||||
users to a site under attacker control, but in certain cases
|
||||
it is safe (and helpful!) to do so. Bug 402210
|
||||
*/
|
||||
function addDomainErrorLink() {
|
||||
// Rather than textContent, we need to treat description as HTML
|
||||
var sd = document.getElementById("errorShortDescText");
|
||||
if (sd) {
|
||||
var desc = getDescription();
|
||||
|
||||
// sanitize description text - see bug 441169
|
||||
|
||||
// First, find the index of the <a> tag we care about, being careful not to
|
||||
// use an over-greedy regex
|
||||
var re = /<a id="cert_domain_link" title="([^"]+)">/;
|
||||
var result = re.exec(desc);
|
||||
if(!result)
|
||||
return;
|
||||
|
||||
// Remove sd's existing children
|
||||
sd.textContent = "";
|
||||
|
||||
// Everything up to the link should be text content
|
||||
sd.appendChild(document.createTextNode(desc.slice(0, result.index)));
|
||||
|
||||
// Now create the link itself
|
||||
var anchorEl = document.createElement("a");
|
||||
anchorEl.setAttribute("id", "cert_domain_link");
|
||||
anchorEl.setAttribute("title", result[1]);
|
||||
anchorEl.appendChild(document.createTextNode(result[1]));
|
||||
sd.appendChild(anchorEl);
|
||||
|
||||
// Finally, append text for anything after the closing </a>
|
||||
sd.appendChild(document.createTextNode(desc.slice(desc.indexOf("</a>") + "</a>".length)));
|
||||
}
|
||||
|
||||
var link = document.getElementById('cert_domain_link');
|
||||
if (!link)
|
||||
return;
|
||||
|
||||
var okHost = link.getAttribute("title");
|
||||
var thisHost = document.location.hostname;
|
||||
var proto = document.location.protocol;
|
||||
|
||||
// If okHost is a wildcard domain ("*.example.com") let's
|
||||
// use "www" instead. "*.example.com" isn't going to
|
||||
// get anyone anywhere useful. bug 432491
|
||||
okHost = okHost.replace(/^\*\./, "www.");
|
||||
|
||||
/* case #1:
|
||||
* example.com uses an invalid security certificate.
|
||||
*
|
||||
* The certificate is only valid for www.example.com
|
||||
*
|
||||
* Make sure to include the "." ahead of thisHost so that
|
||||
* a MitM attack on paypal.com doesn't hyperlink to "notpaypal.com"
|
||||
*
|
||||
* We'd normally just use a RegExp here except that we lack a
|
||||
* library function to escape them properly (bug 248062), and
|
||||
* domain names are famous for having '.' characters in them,
|
||||
* which would allow spurious and possibly hostile matches.
|
||||
*/
|
||||
if (endsWith(okHost, "." + thisHost))
|
||||
link.href = proto + okHost;
|
||||
|
||||
/* case #2:
|
||||
* browser.garage.maemo.org uses an invalid security certificate.
|
||||
*
|
||||
* The certificate is only valid for garage.maemo.org
|
||||
*/
|
||||
if (endsWith(thisHost, "." + okHost))
|
||||
link.href = proto + okHost;
|
||||
}
|
||||
|
||||
function endsWith(haystack, needle) {
|
||||
return haystack.slice(-needle.length) == needle;
|
||||
}
|
||||
|
||||
]]></script>
|
||||
</head>
|
||||
|
||||
<body id="errorPage" dir="&locale.dir;">
|
||||
|
||||
<!-- ERROR ITEM CONTAINER (removed during loading to avoid bug 39098) -->
|
||||
<div id="errorContainer">
|
||||
<div id="errorTitlesContainer">
|
||||
<h1 id="et_generic">&generic.title;</h1>
|
||||
<h1 id="et_dnsNotFound">&dnsNotFound.title;</h1>
|
||||
<h1 id="et_fileNotFound">&fileNotFound.title;</h1>
|
||||
<h1 id="et_malformedURI">&malformedURI.title;</h1>
|
||||
<h1 id="et_protocolNotFound">&protocolNotFound.title;</h1>
|
||||
<h1 id="et_connectionFailure">&connectionFailure.title;</h1>
|
||||
<h1 id="et_netTimeout">&netTimeout.title;</h1>
|
||||
<h1 id="et_redirectLoop">&redirectLoop.title;</h1>
|
||||
<h1 id="et_unknownSocketType">&unknownSocketType.title;</h1>
|
||||
<h1 id="et_netReset">&netReset.title;</h1>
|
||||
<h1 id="et_netOffline">&netOffline.title;</h1>
|
||||
<h1 id="et_netInterrupt">&netInterrupt.title;</h1>
|
||||
<h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
|
||||
<h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
|
||||
<h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
|
||||
<h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
|
||||
<h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
|
||||
<h1 id="et_nssFailure2">&nssFailure2.title;</h1>
|
||||
<h1 id="et_nssBadCert">&nssBadCert.title;</h1>
|
||||
<h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
|
||||
<h1 id="et_remoteXUL">&remoteXUL.title;</h1>
|
||||
<h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
|
||||
</div>
|
||||
<div id="errorDescriptionsContainer">
|
||||
<div id="ed_generic">&generic.longDesc;</div>
|
||||
<div id="ed_dnsNotFound">&dnsNotFound.longDesc2;</div>
|
||||
<div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
|
||||
<div id="ed_malformedURI">&malformedURI.longDesc;</div>
|
||||
<div id="ed_protocolNotFound">&protocolNotFound.longDesc;</div>
|
||||
<div id="ed_connectionFailure">&connectionFailure.longDesc;</div>
|
||||
<div id="ed_netTimeout">&netTimeout.longDesc;</div>
|
||||
<div id="ed_redirectLoop">&redirectLoop.longDesc;</div>
|
||||
<div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div>
|
||||
<div id="ed_netReset">&netReset.longDesc;</div>
|
||||
<div id="ed_netOffline">&netOffline.longDesc2;</div>
|
||||
<div id="ed_netInterrupt">&netInterrupt.longDesc;</div>
|
||||
<div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
|
||||
<div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc2;</div>
|
||||
<div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
|
||||
<div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
|
||||
<div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
|
||||
<div id="ed_nssFailure2">&nssFailure2.longDesc;</div>
|
||||
<div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
|
||||
<div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
|
||||
<div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
|
||||
<div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
<h1 class="errorTitleText" />
|
||||
</div>
|
||||
|
||||
<!-- PAGE CONTAINER (for styling purposes only) -->
|
||||
<div id="errorPageContainer">
|
||||
|
||||
<!-- LONG CONTENT (the section most likely to require scrolling) -->
|
||||
<div id="errorLongContent">
|
||||
|
||||
<!-- Short Description -->
|
||||
<div id="errorShortDesc">
|
||||
<p id="errorShortDescText" />
|
||||
</div>
|
||||
|
||||
<!-- Long Description (Note: See netError.dtd for used XHTML tags) -->
|
||||
<div id="errorLongDesc" />
|
||||
|
||||
<!-- Override section - For ssl errors only. Removed on init for other
|
||||
error types. -->
|
||||
<div id="securityOverrideDiv">
|
||||
<a id="securityOverrideLink" href="javascript:showSecuritySection();" >&securityOverride.linkText;</a>
|
||||
<div id="securityOverrideContent" style="display: none;">&securityOverride.warningContent;</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Retry Button -->
|
||||
<button id="errorTryAgain" onclick="retryThis(this);">&retry.label;</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
- Note: It is important to run the script this way, instead of using
|
||||
- an onload handler. This is because error pages are loaded as
|
||||
- LOAD_BACKGROUND, which means that onload handlers will not be executed.
|
||||
-->
|
||||
<script type="application/javascript">initPage();</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -71,6 +71,12 @@ const PromptHelper = {
|
|||
},
|
||||
|
||||
// User / Password dialog
|
||||
onLoadPassword: function onLoadPassword(dialog) {
|
||||
let user = document.getElementById('prompt-password-user');
|
||||
if (!user.value)
|
||||
user.focus();
|
||||
},
|
||||
|
||||
closePassword: function(confirm) {
|
||||
this.closeDialog(confirm, "prompt-password-dialog");
|
||||
},
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<dialog id="prompt-password-dialog"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="document.getElementById('prompt-password-user').focus()"
|
||||
onload="this.PromptHelper.onLoadPassword(this)"
|
||||
onclose="this.PromptHelper.onClosePassword(this)"
|
||||
script="chrome://browser/content/prompt/prompt.js">
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@ chrome.jar:
|
|||
content/config.xul (content/config.xul)
|
||||
content/config.js (content/config.js)
|
||||
content/aboutCertError.xhtml (content/aboutCertError.xhtml)
|
||||
content/aboutCertError.css (content/aboutCertError.css)
|
||||
content/aboutHome.xhtml (content/aboutHome.xhtml)
|
||||
content/localePicker.xul (content/localePicker.xul)
|
||||
content/localePicker.js (content/localePicker.js)
|
||||
|
@ -72,5 +71,7 @@ chrome.jar:
|
|||
content/LoginManagerChild.js (content/LoginManagerChild.js)
|
||||
content/fullscreen-video.js (content/fullscreen-video.js)
|
||||
content/fullscreen-video.xhtml (content/fullscreen-video.xhtml)
|
||||
content/netError.xhtml (content/netError.xhtml)
|
||||
|
||||
% override chrome://global/content/config.xul chrome://browser/content/config.xul
|
||||
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
|
||||
|
|
|
@ -14,9 +14,6 @@ be replaced at runtime with the name of the server to which the user
|
|||
was trying to connect. -->
|
||||
<!ENTITY certerror.introPara1 "You have asked &brandShortName; to connect
|
||||
securely to <b>#1</b>, but we can't confirm that your connection is secure.">
|
||||
<!ENTITY certerror.introPara2 "Normally, when you try to connect securely,
|
||||
sites will present trusted identification to prove that you are
|
||||
going to the right place. However, this site's identity can't be verified.">
|
||||
|
||||
<!ENTITY certerror.whatShouldIDo.heading "What Should I Do?">
|
||||
<!ENTITY certerror.whatShouldIDo.content "If you usually connect to
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
<!ENTITY contextOpenInNewTab.label "Open Link in New Tab">
|
||||
<!ENTITY contextSaveLink.label "Save Link">
|
||||
<!ENTITY contextSaveImage.label "Save Image">
|
||||
<!ENTITY contextCopyLink.label "Copy Link">
|
||||
<!ENTITY contextShareLink.label "Share Link">
|
||||
<!ENTITY contextShareImage.label "Share Image">
|
||||
<!ENTITY contextBookmarkLink.label "Bookmark Link">
|
||||
|
|
|
@ -7,21 +7,18 @@
|
|||
<!-- Specific error messages -->
|
||||
|
||||
<!ENTITY connectionFailure.title "Unable to connect">
|
||||
<!ENTITY connectionFailure.longDesc "&sharedLongDesc;">
|
||||
<!ENTITY connectionFailure.longDesc "&sharedLongDesc2;">
|
||||
|
||||
<!ENTITY deniedPortAccess.title "This address is restricted">
|
||||
<!ENTITY deniedPortAccess.longDesc "">
|
||||
|
||||
<!ENTITY dnsNotFound.title "Server not found">
|
||||
<!ENTITY dnsNotFound.longDesc "
|
||||
<!ENTITY dnsNotFound.longDesc2 "
|
||||
<ul>
|
||||
<li>Check the address for typing errors such as
|
||||
<strong>ww</strong>.example.com instead of
|
||||
<strong>www</strong>.example.com</li>
|
||||
<li>If you are unable to load any pages, check your computer's network
|
||||
connection.</li>
|
||||
<li>If your computer or network is protected by a firewall or proxy, make sure
|
||||
that &brandShortName; is permitted to access the Web.</li>
|
||||
<li>If you are unable to load any pages, check your device's data or wifi connection.</li>
|
||||
</ul>
|
||||
">
|
||||
|
||||
|
@ -50,7 +47,7 @@
|
|||
">
|
||||
|
||||
<!ENTITY netInterrupt.title "The connection was interrupted">
|
||||
<!ENTITY netInterrupt.longDesc "&sharedLongDesc;">
|
||||
<!ENTITY netInterrupt.longDesc "&sharedLongDesc2;">
|
||||
|
||||
<!ENTITY netOffline.title "Offline mode">
|
||||
<!ENTITY netOffline.longDesc2 "
|
||||
|
@ -74,10 +71,10 @@
|
|||
">
|
||||
|
||||
<!ENTITY netReset.title "The connection was reset">
|
||||
<!ENTITY netReset.longDesc "&sharedLongDesc;">
|
||||
<!ENTITY netReset.longDesc "&sharedLongDesc2;">
|
||||
|
||||
<!ENTITY netTimeout.title "The connection has timed out">
|
||||
<!ENTITY netTimeout.longDesc "&sharedLongDesc;">
|
||||
<!ENTITY netTimeout.longDesc "&sharedLongDesc2;">
|
||||
|
||||
<!ENTITY protocolNotFound.title "The address wasn't understood">
|
||||
<!ENTITY protocolNotFound.longDesc "
|
||||
|
@ -96,12 +93,10 @@
|
|||
">
|
||||
|
||||
<!ENTITY proxyResolveFailure.title "Unable to find the proxy server">
|
||||
<!ENTITY proxyResolveFailure.longDesc "
|
||||
<!ENTITY proxyResolveFailure.longDesc2 "
|
||||
<ul>
|
||||
<li>Check the proxy settings to make sure that they are correct.</li>
|
||||
<li>Check to make sure your computer has a working network connection.</li>
|
||||
<li>If your computer or network is protected by a firewall or proxy, make sure
|
||||
that &brandShortName; is permitted to access the Web.</li>
|
||||
<li>Check to make sure your device has a working data or WiFi connection.</li>
|
||||
</ul>
|
||||
">
|
||||
|
||||
|
@ -140,29 +135,13 @@ be temporary, and you can try again later.</li>
|
|||
</ul>
|
||||
">
|
||||
|
||||
<!ENTITY sharedLongDesc "
|
||||
<!ENTITY sharedLongDesc2 "
|
||||
<ul>
|
||||
<li>The site could be temporarily unavailable or too busy. Try again in a few
|
||||
moments.</li>
|
||||
<li>If you are unable to load any pages, check your computer's network
|
||||
connection.</li>
|
||||
<li>If your computer or network is protected by a firewall or proxy, make sure
|
||||
that &brandShortName; is permitted to access the Web.</li>
|
||||
<li>The site could be temporarily unavailable or too busy. Try again in a few moments.</li>
|
||||
<li>If you are unable to load any pages, check your mobile device's data or wifi connection.</li>
|
||||
</ul>
|
||||
">
|
||||
|
||||
<!ENTITY malwareBlocked.title "Suspected Attack Site!">
|
||||
<!ENTITY malwareBlocked.longDesc "
|
||||
<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>
|
||||
<p>Web site owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p>
|
||||
">
|
||||
|
||||
<!ENTITY phishingBlocked.title "Suspected Web Forgery!">
|
||||
<!ENTITY phishingBlocked.longDesc "
|
||||
<p>Entering any personal information on this page may result in identity theft or other fraud.</p>
|
||||
<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
|
||||
">
|
||||
|
||||
<!ENTITY cspFrameAncestorBlocked.title "Blocked by Content Security Policy">
|
||||
<!ENTITY cspFrameAncestorBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<!ENTITY safeb.blocked.malwarePage.shortDesc "This web page at <span id='malware_sitename'/> has been reported as an attack page and has been blocked based on your security preferences.">
|
||||
<!ENTITY safeb.blocked.malwarePage.longDesc "<p>Attack pages try to install programs that steal private information, use your computer to attack others, or damage your system.</p><p>Some attack pages intentionally distribute harmful software, but many are compromised without the knowledge or permission of their owners.</p>">
|
||||
|
||||
<!ENTITY safeb.blocked.phishingPage.title "Reported Web Forgery!">
|
||||
<!ENTITY safeb.blocked.phishingPage.title2 "Suspected Web Forgery!">
|
||||
<!-- Localization note (safeb.blocked.phishing.shortDesc) - Please don't translate the contents of the <span id="phishing_sitename"/> tag. It will be replaced at runtime with a domain name (e.g. www.badsite.com) -->
|
||||
<!ENTITY safeb.blocked.phishingPage.shortDesc "This web page at <span id='phishing_sitename'/> has been reported as a web forgery and has been blocked based on your security preferences.">
|
||||
<!ENTITY safeb.blocked.phishingPage.longDesc "<p>Web forgeries are designed to trick you into revealing personal or financial information by imitating sources you may trust.</p><p>Entering any information on this web page may result in identity theft or other fraud.</p>">
|
||||
<!ENTITY safeb.blocked.phishingPage.shortDesc2 "Entering any personal information on this page may result in identity theft or other fraud.">
|
||||
<!ENTITY safeb.blocked.phishingPage.longDesc2 "<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>">
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* William Price <bugzilla@mob.rice.edu>
|
||||
* Steven Garrity <steven@silverorange.com>
|
||||
* Henrik Skupin <mozilla@hskupin.info>
|
||||
* Johnathan Nightingale <johnath@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
html {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0 1em;
|
||||
color: black;
|
||||
font-family: "Nokia Sans", Tahoma, sans-serif !important;
|
||||
font-size: 100% !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0 0 .6em 0;
|
||||
border-bottom: 1px solid lightgray;
|
||||
font-size: 160%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 130%;
|
||||
}
|
||||
|
||||
#errorPageContainer {
|
||||
position: relative;
|
||||
min-width: 13em;
|
||||
max-width: 52em;
|
||||
margin: 1em auto;
|
||||
border: 1px solid #FFBD09; /* pale yellow extracted from yellow passport icon */
|
||||
-moz-border-radius: 10px;
|
||||
padding: 3em;
|
||||
-moz-padding-start: 30px;
|
||||
background: url("chrome://global/skin/icons/sslWarning.png") left 0 no-repeat white;
|
||||
-moz-background-origin: content;
|
||||
}
|
||||
|
||||
body[dir="rtl"] #errorPageContainer {
|
||||
background-position: right 0;
|
||||
}
|
||||
|
||||
#errorTitle {
|
||||
-moz-margin-start: 80px;
|
||||
}
|
||||
|
||||
#errorLongContent {
|
||||
-moz-margin-start: 80px;
|
||||
}
|
||||
|
||||
#technicalContent > h2, #expertContent > h2 {
|
||||
background : url("chrome://browser/skin/images/section-expanded-16.png") left 0 no-repeat;
|
||||
}
|
||||
|
||||
#technicalContent[collapsed] > h2,
|
||||
#expertContent[collapsed] > h2 {
|
||||
background-image: url("chrome://browser/skin/images/section-collapsed-16.png");
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 850 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 886 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 631 B |
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче