--- a/accessible/src/base/nsAccEvent.cpp
+++ b/accessible/src/base/nsAccEvent.cpp
@@ -309,21 +309,26 @@ nsAccReorderEvent::HasAccessibleInReason
////////////////////////////////////////////////////////////////////////////////
// nsAccStateChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccStateChangeEvent, nsAccEvent,
nsIAccessibleStateChangeEvent)
+// Note: we pass in eAllowDupes to the base class because we don't currently
+// support correct state change coalescence (XXX Bug 569356). Also we need to
+// decide how to coalesce events created via accessible (instead of node).
nsAccStateChangeEvent::
nsAccStateChangeEvent(nsIAccessible *aAccessible,
PRUint32 aState, PRBool aIsExtraState,
- PRBool aIsEnabled):
- nsAccEvent(::nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible),
+ PRBool aIsEnabled, PRBool aIsAsynch,
+ EIsFromUserInput aIsFromUserInput):
+ nsAccEvent(nsIAccessibleEvent::EVENT_STATE_CHANGE, aAccessible, aIsAsynch,
+ aIsFromUserInput, eAllowDupes),
mState(aState), mIsExtraState(aIsExtraState), mIsEnabled(aIsEnabled)
{
}
nsAccStateChangeEvent::
nsAccStateChangeEvent(nsIDOMNode *aNode,
PRUint32 aState, PRBool aIsExtraState,
PRBool aIsEnabled):
@@ -374,22 +379,30 @@ nsAccStateChangeEvent::IsEnabled(PRBool
////////////////////////////////////////////////////////////////////////////////
// nsAccTextChangeEvent
////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS_INHERITED1(nsAccTextChangeEvent, nsAccEvent,
nsIAccessibleTextChangeEvent)
+// Note: we pass in eAllowDupes to the base class because we don't support text
+// events coalescence. We fire delayed text change events in nsDocAccessible but
+// we continue to base the event off the accessible object rather than just the
+// node. This means we won't try to create an accessible based on the node when
+// we are ready to fire the event and so we will no longer assert at that point
+// if the node was removed from the document. Either way, the AT won't work with
+// a defunct accessible so the behaviour should be equivalent.
+// XXX revisit this when coalescence is faster (eCoalesceFromSameSubtree)
nsAccTextChangeEvent::
nsAccTextChangeEvent(nsIAccessible *aAccessible,
PRInt32 aStart, PRUint32 aLength, PRBool aIsInserted,
PRBool aIsAsynch, EIsFromUserInput aIsFromUserInput) :
nsAccEvent(aIsInserted ? nsIAccessibleEvent::EVENT_TEXT_INSERTED : nsIAccessibleEvent::EVENT_TEXT_REMOVED,
- aAccessible, aIsAsynch, aIsFromUserInput),
+ aAccessible, aIsAsynch, aIsFromUserInput, eAllowDupes),
mStart(aStart), mLength(aLength), mIsInserted(aIsInserted)
{
#ifdef XP_WIN
nsCOMPtr<nsIAccessibleText> textAccessible = do_QueryInterface(aAccessible);
NS_ASSERTION(textAccessible, "Should not be firing test change event for non-text accessible!!!");
if (textAccessible) {
textAccessible->GetText(aStart, aStart + aLength, mModifiedText);
}
--- a/accessible/src/base/nsAccEvent.h
+++ b/accessible/src/base/nsAccEvent.h
@@ -193,17 +193,18 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAccReord
class nsAccStateChangeEvent: public nsAccEvent,
public nsIAccessibleStateChangeEvent
{
public:
nsAccStateChangeEvent(nsIAccessible *aAccessible,
PRUint32 aState, PRBool aIsExtraState,
- PRBool aIsEnabled);
+ PRBool aIsEnabled, PRBool aIsAsynch = PR_FALSE,
+ EIsFromUserInput aIsFromUserInput = eAutoDetect);
nsAccStateChangeEvent(nsIDOMNode *aNode,
PRUint32 aState, PRBool aIsExtraState,
PRBool aIsEnabled);
nsAccStateChangeEvent(nsIDOMNode *aNode,
PRUint32 aState, PRBool aIsExtraState);
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -978,20 +978,23 @@ void nsDocAccessible::ScrollPositionDidC
////////////////////////////////////////////////////////////////////////////////
// nsIObserver
NS_IMETHODIMP nsDocAccessible::Observe(nsISupports *aSubject, const char *aTopic,
const PRUnichar *aData)
{
if (!nsCRT::strcmp(aTopic,"obs_documentCreated")) {
// State editable will now be set, readonly is now clear
+ // Normally we only fire delayed events created from the node, not an
+ // accessible object. See the nsAccStateChangeEvent constructor for details
+ // about this exceptional case.
nsRefPtr<nsAccEvent> event =
new nsAccStateChangeEvent(this, nsIAccessibleStates::EXT_STATE_EDITABLE,
PR_TRUE, PR_TRUE);
- nsEventShell::FireEvent(event);
+ FireDelayedAccessibleEvent(event);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsIDocumentObserver
@@ -1484,21 +1487,24 @@ nsDocAccessible::FireTextChangeEventForT
if (NS_FAILED(rv))
return;
rv = textAccessible->ContentToRenderedOffset(frame, start + length,
&renderedEndOffset);
if (NS_FAILED(rv))
return;
+ // Normally we only fire delayed events created from the node, not an
+ // accessible object. See the nsAccTextChangeEvent constructor for details
+ // about this exceptional case.
nsRefPtr<nsAccEvent> event =
new nsAccTextChangeEvent(accessible, offset,
renderedEndOffset - renderedStartOffset,
aIsInserted, PR_FALSE);
- nsEventShell::FireEvent(event);
+ FireDelayedAccessibleEvent(event);
FireValueChangeForTextFields(accessible);
}
}
already_AddRefed<nsAccEvent>
nsDocAccessible::CreateTextChangeEventForNode(nsAccessible *aContainerAccessible,
nsIDOMNode *aChangeNode,
@@ -1986,21 +1992,24 @@ nsDocAccessible::InvalidateCacheSubtree(
return;
if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
// When a node is hidden or removed, the text in an ancestor hyper text will lose characters
// At this point we still have the frame and accessible for this node if there was one
// XXX Collate events when a range is deleted
// XXX We need a way to ignore SplitNode and JoinNode() when they
// do not affect the text within the hypertext
+ // Normally we only fire delayed events created from the node, not an
+ // accessible object. See the nsAccTextChangeEvent constructor for details
+ // about this exceptional case.
nsRefPtr<nsAccEvent> textChangeEvent =
CreateTextChangeEventForNode(containerAccessible, childNode, childAccessible,
PR_FALSE, isAsynch);
if (textChangeEvent) {
- nsEventShell::FireEvent(textChangeEvent);
+ FireDelayedAccessibleEvent(textChangeEvent);
}
}
}
// We need to get an accessible for the mutation event's container node
// If there is no accessible for that node, we need to keep moving up the parent
// chain so there is some accessible.
// We will use this accessible to fire the accessible mutation event.
--- a/accessible/tests/mochitest/events/Makefile.in
+++ b/accessible/tests/mochitest/events/Makefile.in
@@ -56,15 +56,16 @@ include $(topsrcdir)/config/rules.mk
test_dragndrop.html \
test_flush.html \
test_focus.html \
test_focus.xul \
test_focus_name.html \
test_focusdoc.html \
test_mutation.html \
test_scroll.xul \
+ test_statechange.html \
test_text.html \
test_tree.xul \
test_valuechange.html \
$(NULL)
libs:: $(_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/a11y/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/events/test_statechange.html
@@ -0,0 +1,102 @@
+<html>
+
+<head>
+ <title>Accessible state change event testing</title>
+
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/MochiKit/packed.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/a11y/accessible/common.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/a11y/accessible/events.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/a11y/accessible/states.js"></script>
+
+ <script type="application/javascript">
+ ////////////////////////////////////////////////////////////////////////////
+ // Invokers
+
+ function makeEditableDoc(aDocNode, aIsEnabled)
+ {
+ this.DOMNode = aDocNode;
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_STATE_CHANGE, getAccessible(this.DOMNode))
+ ];
+
+ this.invoke = function editabledoc_invoke() {
+ // Note: this should fire an EVENT_STATE_CHANGE
+ this.DOMNode.designMode = 'on';
+ };
+
+ this.check = function editabledoc_check(aEvent) {
+
+ testStates(aDocNode, 0, EXT_STATE_EDITABLE);
+
+ var event = null;
+ try {
+ var event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
+ } catch (e) {
+ ok(false, "State change event was expected");
+ }
+
+ if (!event) { return; }
+
+ ok(event.isExtraState(), "Extra state change was expected");
+ is(event.state, EXT_STATE_EDITABLE, "Wrong state of statechange event");
+ ok(event.isEnabled(), "Expected editable state to be enabled");
+ }
+
+ this.getID = function editabledoc_getID() {
+ return prettyName(aDocNode) + " editable state changed";
+ };
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Do tests
+
+ var gQueue = null;
+
+ // var gA11yEventDumpID = "eventdump"; // debug stuff
+
+ function doTests()
+ {
+ gQueue = new eventQueue();
+
+ // Test delayed editable state change
+ var doc = document.getElementById("iframe").contentDocument;
+ gQueue.push(new makeEditableDoc(doc));
+
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTests);
+ </script>
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=564471"
+ title="Make state change events async">
+ Mozilla Bug 564471
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="testContainer">
+ <iframe id="iframe"></iframe>
+ </div>
+ <div id="eventdump"></div>
+</body>
+</html>
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -82,17 +82,17 @@ function nsContextMenu(aXulMenu, aBrowse
this.linkURI = null;
this.linkProtocol = null;
this.inFrame = false;
this.hasBGImage = false;
this.isTextSelected = false;
this.isContentSelected = false;
this.shouldDisplay = true;
this.isDesignMode = false;
- this.possibleSpellChecking = false;
+ this.onEditableArea = false;
this.ellipsis = "\u2026";
try {
this.ellipsis = gPrefService.getComplexValue("intl.ellipsis",
Ci.nsIPrefLocalizedString).data;
} catch (e) { }
// Initialize new menu.
this.initMenu(aXulMenu, aBrowser);
@@ -362,17 +362,17 @@ nsContextMenu.prototype = {
this.showItem("context-blockimage", this.onImage && hostLabel &&
!gPrivateBrowsingUI.privateBrowsingEnabled);
},
initSpellingItems: function() {
var canSpell = InlineSpellCheckerUI.canSpellCheck;
var onMisspelling = InlineSpellCheckerUI.overMisspelling;
this.showItem("spell-check-enabled", canSpell);
- this.showItem("spell-separator", canSpell || this.possibleSpellChecking);
+ this.showItem("spell-separator", canSpell || this.onEditableArea);
if (canSpell) {
document.getElementById("spell-check-enabled")
.setAttribute("checked", InlineSpellCheckerUI.enabled);
}
this.showItem("spell-add-to-dictionary", onMisspelling);
// suggestion list
@@ -390,17 +390,17 @@ nsContextMenu.prototype = {
// dictionary list
this.showItem("spell-dictionaries", InlineSpellCheckerUI.enabled);
if (canSpell) {
var dictMenu = document.getElementById("spell-dictionaries-menu");
var dictSep = document.getElementById("spell-language-separator");
InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep);
this.showItem("spell-add-dictionaries-main", false);
}
- else if (this.possibleSpellChecking) {
+ else if (this.onEditableArea) {
// when there is no spellchecker but we might be able to spellcheck
// add the add to dictionaries item. This will ensure that people
// with no dictionaries will be able to download them
this.showItem("spell-add-dictionaries-main", true);
}
else
this.showItem("spell-add-dictionaries-main", false);
},
@@ -498,17 +498,17 @@ nsContextMenu.prototype = {
this.onLink = false;
this.linkURL = "";
this.linkURI = null;
this.linkProtocol = "";
this.onMathML = false;
this.inFrame = false;
this.hasBGImage = false;
this.bgImageURL = "";
- this.possibleSpellChecking = false;
+ this.onEditableArea = false;
// Clear any old spellchecking items from the menu, this used to
// be in the menu hiding code but wasn't getting called in all
// situations. Here, we can ensure it gets cleaned up any time the
// menu is shown. Note: must be before uninit because that clears the
// internal vars
InlineSpellCheckerUI.clearSuggestionsFromMenu();
InlineSpellCheckerUI.clearDictionaryListFromMenu();
@@ -547,26 +547,26 @@ nsContextMenu.prototype = {
this.onAudio = true;
this.mediaURL = this.target.currentSrc || this.target.src;
}
else if (this.target instanceof HTMLInputElement ) {
this.onTextInput = this.isTargetATextBox(this.target);
// allow spellchecking UI on all writable text boxes except passwords
if (this.onTextInput && ! this.target.readOnly &&
this.target.type != "password") {
- this.possibleSpellChecking = true;
+ this.onEditableArea = true;
InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
}
this.onKeywordField = this.isTargetAKeywordField(this.target);
}
else if (this.target instanceof HTMLTextAreaElement) {
this.onTextInput = true;
if (!this.target.readOnly) {
- this.possibleSpellChecking = true;
+ this.onEditableArea = true;
InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
}
}
else if (this.target instanceof HTMLHtmlElement) {
var bodyElt = this.target.ownerDocument.body;
if (bodyElt) {
let computedURL;
@@ -657,49 +657,51 @@ nsContextMenu.prototype = {
this.onMathML = true;
// See if the user clicked in a frame.
var docDefaultView = this.target.ownerDocument.defaultView;
if (docDefaultView != docDefaultView.top)
this.inFrame = true;
// if the document is editable, show context menu like in text inputs
- var win = this.target.ownerDocument.defaultView;
- if (win) {
- var isEditable = false;
- try {
- var editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIEditingSession);
- if (editingSession.windowIsEditable(win) &&
- this.getComputedStyle(this.target, "-moz-user-modify") == "read-write") {
- isEditable = true;
+ if (!this.onEditableArea) {
+ var win = this.target.ownerDocument.defaultView;
+ if (win) {
+ var isEditable = false;
+ try {
+ var editingSession = win.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIEditingSession);
+ if (editingSession.windowIsEditable(win) &&
+ this.getComputedStyle(this.target, "-moz-user-modify") == "read-write") {
+ isEditable = true;
+ }
}
- }
- catch(ex) {
- // If someone built with composer disabled, we can't get an editing session.
- }
+ catch(ex) {
+ // If someone built with composer disabled, we can't get an editing session.
+ }
- if (isEditable) {
- this.onTextInput = true;
- this.onKeywordField = false;
- this.onImage = false;
- this.onLoadedImage = false;
- this.onCompletedImage = false;
- this.onMathML = false;
- this.inFrame = false;
- this.hasBGImage = false;
- this.isDesignMode = true;
- this.possibleSpellChecking = true;
- InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
- var canSpell = InlineSpellCheckerUI.canSpellCheck;
- InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
- this.showItem("spell-check-enabled", canSpell);
- this.showItem("spell-separator", canSpell);
+ if (isEditable) {
+ this.onTextInput = true;
+ this.onKeywordField = false;
+ this.onImage = false;
+ this.onLoadedImage = false;
+ this.onCompletedImage = false;
+ this.onMathML = false;
+ this.inFrame = false;
+ this.hasBGImage = false;
+ this.isDesignMode = true;
+ this.onEditableArea = true;
+ InlineSpellCheckerUI.init(editingSession.getEditorForWindow(win));
+ var canSpell = InlineSpellCheckerUI.canSpellCheck;
+ InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
+ this.showItem("spell-check-enabled", canSpell);
+ this.showItem("spell-separator", canSpell);
+ }
}
}
},
// Returns the computed style attribute for the given element.
getComputedStyle: function(aElem, aProp) {
return aElem.ownerDocument
.defaultView
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -65,16 +65,17 @@ include $(topsrcdir)/config/rules.mk
test_bug364677.html \
bug364677-data.xml \
bug364677-data.xml^headers^ \
test_offline_gzip.html \
gZipOfflineChild.html \
gZipOfflineChild.html^headers^ \
gZipOfflineChild.cacheManifest \
gZipOfflineChild.cacheManifest^headers^ \
+ test_bug452451.html \
$(NULL)
# The following tests are disabled because they are unreliable:
# browser_bug423833.js is bug 428712
# browser_sanitize-download-history.js is bug 432425
#
# browser_sanitizeDialog_treeView.js is disabled until the tree view is added
# back to the clear recent history dialog (santize.xul), if it ever is (bug
--- a/browser/base/content/test/browser_bug321000.js
+++ b/browser/base/content/test/browser_bug321000.js
@@ -58,72 +58,31 @@ var gTests = [
];
// Test for bug 23485 and bug 321000.
// Urlbar should strip newlines,
// search bar should replace newlines with spaces.
function test() {
waitForExplicitFinish();
+ let cbHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
+ getService(Ci.nsIClipboardHelper);
+
// Put a multi-line string in the clipboard.
- info("About to put a string in clipboard");
- Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
- .copyString(kTestString);
-
// Setting the clipboard value is an async OS operation, so we need to poll
// the clipboard for valid data before going on.
- setTimeout(poll_clipboard, 100);
-}
-
-var runCount = 0;
-function poll_clipboard() {
- // Poll for a maximum of 5s (each run happens after 100ms).
- if (++runCount > 50) {
- // Log the failure.
- ok(false, "Timed out while polling clipboard for pasted data");
- // Cleanup and interrupt the test.
- finish_test();
- return;
- }
-
- info("Polling clipboard cycle " + runCount);
- var clip = Cc["@mozilla.org/widget/clipboard;1"].
- getService(Ci.nsIClipboard);
- var trans = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- trans.addDataFlavor("text/unicode");
- var str = new Object();
- try {
- // This code could throw if the clipboard is not set yet.
- clip.getData(trans, clip.kGlobalClipboard);
- trans.getTransferData("text/unicode", str, {});
- str = str.value.QueryInterface(Ci.nsISupportsString);
- }
- catch(ex) {}
-
- if (kTestString == str) {
- next_test();
- }
- else
- setTimeout(poll_clipboard, 100);
+ waitForClipboard(kTestString, function() { cbHelper.copyString(kTestString); },
+ next_test, finish);
}
function next_test() {
- if (gTests.length) {
- var currentTest = gTests.shift();
- test_paste(currentTest);
- }
- else {
- // No more tests to run.
- // Clear the clipboard, emptyClipboard would not clear the native one, so
- // we are setting it to an empty string.
- Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
- .copyString("");
+ if (gTests.length)
+ test_paste(gTests.shift());
+ else
finish();
- }
}
function test_paste(aCurrentTest) {
var element = aCurrentTest.element;
// Register input listener.
var inputListener = {
test: aCurrentTest,
--- a/browser/base/content/test/browser_bug556061.js
+++ b/browser/base/content/test/browser_bug556061.js
@@ -30,129 +30,96 @@
* 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 ***** */
-let cbSvc = Cc["@mozilla.org/widget/clipboard;1"].
- getService(Ci.nsIClipboard);
-
let testURL = "http://example.org/browser/browser/base/content/test/dummy_page.html";
let testActionURL = "moz-action:switchtab," + testURL;
let testTab;
-let clipboardText = "";
-let currentClipboardText = null;
-let clipboardPolls = 0;
-
-// The clipboard can have a string value without it being the one we expect, so
-// we'll check the current value against the previous value to see if it changed.
-// We can do this because our expected clipboard value should be different each
-// time we wait.
-function waitForClipboard() {
- // Poll for a maximum of 5s (each run happens after 100ms).
- if (++clipboardPolls > 50) {
- // Log the failure.
- ok(false, "Timed out while polling clipboard for pasted data");
- // Cleanup and interrupt the test.
- cleanup();
- return;
- }
-
- let xferable = Cc["@mozilla.org/widget/transferable;1"].
- createInstance(Ci.nsITransferable);
- xferable.addDataFlavor("text/unicode");
- cbSvc.getData(xferable, cbSvc.kGlobalClipboard);
- try {
- let data = {};
- xferable.getTransferData("text/unicode", data, {});
- currentClipboardText = data.value.QueryInterface(Ci.nsISupportsString).data;
- } catch (e) {}
-
- if (currentClipboardText == clipboardText) {
- setTimeout(waitForClipboard, 100);
- } else {
- clipboardText = currentClipboardText;
- runNextTest();
- }
-}
function runNextTest() {
- // reset clipboard polling count
- clipboardPolls = 0;
- // run next test, just assume we won't call in here without more tests
- tests.shift()();
+ if (tests.length) {
+ let t = tests.shift();
+ waitForClipboard(t.expected, t.setup, function() {
+ t.success();
+ runNextTest();
+ }, cleanup);
+ }
+ else {
+ cleanup();
+ }
}
function cleanup() {
gBrowser.removeTab(testTab);
finish();
}
-// Tests in order. Some tests setup for the next actual test...
let tests = [
- function () {
- // Set the urlbar to include the moz-action
- gURLBar.value = testActionURL;
- is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
-
- // Focus the urlbar so we can select it all & copy
- gURLBar.focus();
- gURLBar.select();
- goDoCommand("cmd_copy");
- waitForClipboard();
- },
- function () {
- is(clipboardText, testURL, "Clipboard has the correct value");
- // We shouldn't have changed the value of gURLBar
- is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
-
- // Set selectionStart/End manually and make sure it matches the substring
- gURLBar.selectionStart = 0;
- gURLBar.selectionEnd = 10;
- goDoCommand("cmd_copy");
- waitForClipboard();
- },
- function () {
- is(clipboardText, testURL.substring(0, 10), "Clipboard has the correct value");
- is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
+ {
+ expected: testURL,
+ setup: function() {
+ gURLBar.value = testActionURL;
+ is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
- // Setup for cut test...
- // Select all
- gURLBar.select();
- goDoCommand("cmd_cut");
- waitForClipboard();
+ // Focus the urlbar so we can select it all & copy
+ gURLBar.focus();
+ gURLBar.select();
+ goDoCommand("cmd_copy");
+ },
+ success: function() {
+ is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
+ }
},
- function () {
- is(clipboardText, testURL, "Clipboard has the correct value");
- is(gURLBar.value, "", "gURLBar.value is now empty");
-
- // Reset urlbar value
- gURLBar.value = testActionURL;
- // Sanity check that we have the right value
- is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
+ {
+ expected: testURL.substring(0, 10),
+ setup: function() {
+ // Set selectionStart/End manually and make sure it matches the substring
+ gURLBar.selectionStart = 0;
+ gURLBar.selectionEnd = 10;
+ goDoCommand("cmd_copy");
+ },
+ success: function() {
+ is(gURLBar.value, testActionURL, "gURLBar.value didn't change when copying");
+ }
+ },
+ {
+ expected: testURL,
+ setup: function() {
+ // Setup for cut test...
+ // Select all
+ gURLBar.select();
+ goDoCommand("cmd_cut");
+ },
+ success: function() {
+ is(gURLBar.value, "", "gURLBar.value is now empty");
+ }
+ },
+ {
+ expected: testURL.substring(testURL.length - 10, testURL.length),
+ setup: function() {
+ // Reset urlbar value
+ gURLBar.value = testActionURL;
+ // Sanity check that we have the right value
+ is(gURLBar.value, testActionURL, "gURLBar.value starts with correct value");
- // Now just select part of the value & cut that.
- gURLBar.selectionStart = testURL.length - 10;
- gURLBar.selectionEnd = testURL.length;
-
- goDoCommand("cmd_cut");
- waitForClipboard();
- },
- function () {
- is(clipboardText, testURL.substring(testURL.length - 10, testURL.length),
- "Clipboard has the correct value");
- is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value");
-
- // We're done, so just finish up
- cleanup();
+ // Now just select part of the value & cut that.
+ gURLBar.selectionStart = testURL.length - 10;
+ gURLBar.selectionEnd = testURL.length;
+ goDoCommand("cmd_cut");
+ },
+ success: function() {
+ is(gURLBar.value, testURL.substring(0, testURL.length - 10), "gURLBar.value has the correct value");
+ }
}
-]
+];
function test() {
waitForExplicitFinish();
testTab = gBrowser.addTab();
gBrowser.selectedTab = testTab;
// Kick off the testing
runNextTest();
--- a/browser/base/content/test/subtst_contextmenu.html
+++ b/browser/base/content/test/subtst_contextmenu.html
@@ -13,11 +13,14 @@ Browser context menu subtest.
<img id="test-image" src="ctxmenu-image.png">
<canvas id="test-canvas" width="100" height="100" style="background-color: blue"></canvas>
<video id="test-video-ok" src="video.ogg" width="100" height="100" style="background-color: green"></video>
<video id="test-video-bad" src="bogus.duh" width="100" height="100" style="background-color: orange"></video>
<video id="test-video-bad2" width="100" height="100" style="background-color: yellow">
<source src="bogus.duh" type="video/durrrr;">
</video>
<iframe id="test-iframe" width="98" height="98" style="border: 1px solid black"></iframe>
+<textarea id="test-textarea">chssseesbbbie</textarea> <!-- a weird word which generates only one suggestion -->
+<div id="test-contenteditable" contenteditable="true">chssseefsbbbie</div> <!-- a more weird word which generates no suggestions -->
+<input id="test-input-spellcheck" type="text" spellcheck="true" autofocus value="prodkjfgigrty"> <!-- this one also generates one suggestion -->
</body>
</html>
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/test_bug452451.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=452451
+-->
+<head>
+ <title>Test for Bug 452451</title>
+ <script type="application/javascript" src="/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=452451">Mozilla Bug 452451</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 452451 **/
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ const prefs = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefBranch);
+
+ ok(prefs.getBoolPref("javascript.options.relimit"),
+ "relimit should be enabled by default");
+
+ /**
+ * Following tests are inspired from:
+ * js/src/tests/js1_5/extensions/regress-330569.js
+ */
+
+ var s;
+ const expected = 'InternalError: regular expression too complex';
+
+ s = '<!DOCTYPE HTML PUBLIC>' +
+ '<html>\n' +
+ '<head>\n' +
+ '<meta http-equiv="content-type" content="text/html">\n' +
+ '<title></title>\n'+
+ '</head>\n' +
+ '<body>\n' +
+ '<!-- hello -->\n' +
+ '<script language="JavaScript">\n' +
+ 'var s = document. body. innerHTML;\n' +
+ 'var d = s. replace (/<!--(.*|\n)*-->/, "");\n' +
+ '<\/script>\n' +
+ '<\/body>\n' +
+ '<\/html>\n';
+
+ try {
+ /<!--(.*|\n)*-->/.exec(s);
+ }
+ catch(ex) {
+ actual = ex;
+ }
+
+ is(actual, expected, "reg exp too complex error should have been thrown");
+
+ function testre( re, n )
+ {
+ var txt = '';
+ for (var i= 0; i <= n; ++i) {
+ txt += ',';
+ re.test(txt);
+ }
+ }
+
+ try {
+ testre( /(?:,*)*x/, 22 );
+ }
+ catch(ex) {
+ actual = ex;
+ }
+
+ is(actual, expected, "reg exp too complex error should have been thrown");
+
+ try {
+ testre( /(?:,|,)*x/, 22 );
+ }
+ catch(ex) {
+ actual = ex;
+ }
+
+ is(actual, expected, "reg exp too complex error should have been thrown");
+
+ try {
+ testre( /(?:,|,|,|,|,)*x/, 10 );
+ }
+ catch(ex) {
+ actual = ex;
+ }
+
+ is(actual, expected, "reg exp too complex error should have been thrown");
+</script>
+</pre>
+</body>
+</html>
--- a/browser/base/content/test/test_contextmenu.html
+++ b/browser/base/content/test/test_contextmenu.html
@@ -44,24 +44,37 @@ function getVisibleMenuItems(aMenu) {
if (item.hidden)
continue;
var key = item.accessKey;
if (key)
key = key.toLowerCase();
if (item.nodeName == "menuitem") {
- ok(item.id, "child menuitem #" + i + " has an ID");
+ var isSpellSuggestion = item.className == "spell-suggestion";
+ if (isSpellSuggestion) {
+ is(item.id, "", "child menuitem #" + i + " is a spelling suggestion");
+ } else {
+ ok(item.id, "child menuitem #" + i + " has an ID");
+ }
ok(item.label.length, "menuitem " + item.id + " has a label");
- ok(key, "menuitem " + item.id + " has an access key");
- if (accessKeys[key])
- ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
- else
- accessKeys[key] = item.id;
- items.push(item.id);
+ if (isSpellSuggestion) {
+ is(key, "", "Spell suggestions shouldn't have an access key");
+ items.push("*" + item.label);
+ } else if (item.id.indexOf("spell-check-dictionary-") != 0 &&
+ item.id != "spell-no-suggestions") {
+ ok(key, "menuitem " + item.id + " has an access key");
+ if (accessKeys[key])
+ ok(false, "menuitem " + item.id + " has same accesskey as " + accessKeys[key]);
+ else
+ accessKeys[key] = item.id;
+ }
+ if (!isSpellSuggestion) {
+ items.push(item.id);
+ }
items.push(!item.disabled);
} else if (item.nodeName == "menuseparator") {
ok(true, "--- seperator id is " + item.id);
items.push("---");
items.push(null);
} else if (item.nodeName == "menu") {
ok(item.id, "child menu #" + i + " has an ID");
ok(key, "menu has an access key");
@@ -301,17 +314,88 @@ function runTest(testNum) {
"context-printframe", true,
"---", null,
"context-viewframesource", true,
"context-viewframeinfo", true], null,
"---", null,
"context-viewsource", true,
"context-viewinfo", true]);
closeContextMenu();
+ openContextMenuFor(textarea); // Invoke context menu for next test.
+ break;
+ case 12:
+ // Context menu for textarea
+ checkContextMenu(["*chubbiness", true, // spelling suggestion
+ "spell-add-to-dictionary", true,
+ "---", null,
+ "context-undo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+
+ closeContextMenu();
+ openContextMenuFor(contenteditable); // Invoke context menu for next test.
+ break;
+
+ case 13:
+ // Context menu for contenteditable
+ checkContextMenu(["spell-no-suggestions", false,
+ "spell-add-to-dictionary", true,
+ "---", null,
+ "context-undo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+
+ closeContextMenu();
+ openContextMenuFor(inputspell); // Invoke context menu for next test.
+ break;
+
+ case 14:
+ // Context menu for spell-check input
+ checkContextMenu(["*prodigality", true, // spelling suggestion
+ "spell-add-to-dictionary", true,
+ "---", null,
+ "context-undo", false,
+ "---", null,
+ "context-cut", false,
+ "context-copy", false,
+ "context-paste", null, // ignore clipboard state
+ "context-delete", false,
+ "---", null,
+ "context-selectall", true,
+ "---", null,
+ "spell-check-enabled", true,
+ "spell-dictionaries", true,
+ ["spell-check-dictionary-en-US", true,
+ "---", null,
+ "spell-add-dictionaries", true], null]);
+
+ closeContextMenu();
subwindow.close();
SimpleTest.finish();
return;
/*
* Other things that would be nice to test:
* - selected text
* - spelling / misspelled word (in text input?)
@@ -326,17 +410,18 @@ function runTest(testNum) {
return;
}
}
var testNum = 1;
var subwindow, chromeWin, contextMenu;
-var text, link, mailto, input, img, canvas, video, iframe;
+var text, link, mailto, input, img, canvas, video, iframe,
+ textarea, contenteditable, inputspell;
function startTest() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
chromeWin = subwindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
@@ -351,16 +436,19 @@ function startTest() {
mailto = subwindow.document.getElementById("test-mailto");
input = subwindow.document.getElementById("test-input");
img = subwindow.document.getElementById("test-image");
canvas = subwindow.document.getElementById("test-canvas");
video_ok = subwindow.document.getElementById("test-video-ok");
video_bad = subwindow.document.getElementById("test-video-bad");
video_bad2 = subwindow.document.getElementById("test-video-bad2");
iframe = subwindow.document.getElementById("test-iframe");
+ textarea = subwindow.document.getElementById("test-textarea");
+ contenteditable = subwindow.document.getElementById("test-contenteditable");
+ inputspell = subwindow.document.getElementById("test-input-spellcheck");
contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false);
runTest(1);
}
// We open this in a separate window, because the Mochitests run inside a frame.
// The frame causes an extra menu item, and prevents running the test
// standalone (ie, clicking the test name in the Mochitest window) to see
--- a/build/autoconf/nss.m4
+++ b/build/autoconf/nss.m4
@@ -4,17 +4,17 @@
# Based upon gtk.m4 (also PD) by Owen Taylor
dnl AM_PATH_NSS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
dnl Test for NSS, and define NSS_CFLAGS and NSS_LIBS
AC_DEFUN(AM_PATH_NSS,
[dnl
AC_ARG_WITH(nss-prefix,
- [ --with-nss-prefix=PFX Prefix where NSS is installed],
+ [ --with-nss-prefix=PFX Prefix where NSS is installed],
nss_config_prefix="$withval",
nss_config_prefix="")
AC_ARG_WITH(nss-exec-prefix,
[ --with-nss-exec-prefix=PFX
Exec prefix where NSS is installed],
nss_config_exec_prefix="$withval",
nss_config_exec_prefix="")
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -144,24 +144,26 @@ stl_compiler = gcc
else
ifdef _MSC_VER
stl_compiler = msvc
endif
endif
endif
ifdef stl_compiler
-stl-wrappers-sentinel: $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
+STL_WRAPPERS_SENTINEL = $(DIST)/stl_wrappers/sentinel
+
+$(STL_WRAPPERS_SENTINEL): $(srcdir)/make-stl-wrappers.py $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers $(GLOBAL_DEPS)
$(PYTHON) $(srcdir)/make-stl-wrappers.py stl_wrappers $(stl_compiler) $(srcdir)/$(stl_compiler)-stl-wrapper.template.h $(srcdir)/stl-headers
$(PYTHON) $(srcdir)/nsinstall.py stl_wrappers $(DIST)
- touch stl-wrappers-sentinel
+ touch $(STL_WRAPPERS_SENTINEL)
-export:: stl-wrappers-sentinel
+export:: $(STL_WRAPPERS_SENTINEL)
-GARBAGE += stl-wrappers-sentinel
+GARBAGE += $(STL_WRAPPERS_SENTINEL)
GARBAGE_DIRS += stl_wrappers
endif
install::
$(SYSINSTALL) $(IFLAGS1) $(DEPTH)/mozilla-config.h $(DESTDIR)$(includedir)
GARBAGE += \
$(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) buildid $(srcdir)/*.pyc
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -591,16 +591,17 @@ MOZILLA_OFFICIAL = @MOZILLA_OFFICIAL@
# Win32 options
MOZ_BROWSE_INFO = @MOZ_BROWSE_INFO@
MOZ_TOOLS_DIR = @MOZ_TOOLS_DIR@
MOZ_QUANTIFY = @MOZ_QUANTIFY@
MSMANIFEST_TOOL = @MSMANIFEST_TOOL@
WIN32_REDIST_DIR = @WIN32_REDIST_DIR@
WIN32_CRT_SRC_DIR = @WIN32_CRT_SRC_DIR@
MOZ_MEMORY_LDFLAGS = @MOZ_MEMORY_LDFLAGS@
+MOZ_CRT_CPU_ARCH = @MOZ_CRT_CPU_ARCH@
# This is for custom CRT building
ifdef MOZ_MEMORY
ifdef WIN32_CRT_SRC_DIR
DLLFLAGS = @DLLFLAGS@
endif
endif
--- a/configure.in
+++ b/configure.in
@@ -105,17 +105,17 @@ dnl ====================================
_SUBDIR_HOST_CFLAGS="$HOST_CFLAGS"
_SUBDIR_HOST_CXXFLAGS="$HOST_CXXFLAGS"
_SUBDIR_HOST_LDFLAGS="$HOST_LDFLAGS"
_SUBDIR_CONFIG_ARGS="$ac_configure_args"
dnl Set the version number of the libs included with mozilla
dnl ========================================================
MOZJPEG=62
-MOZPNG=10400
+MOZPNG=10401
MOZZLIB=0x1230
NSPR_VERSION=4
NSS_VERSION=3
dnl Set the minimum version of toolkit libs used by mozilla
dnl ========================================================
GLIB_VERSION=1.2.0
LIBIDL_VERSION=0.6.3
@@ -210,22 +210,22 @@ case "$target" in
if test -z "$CXX"; then CXX=g++-4.2; fi
;;
esac
fi
COMPILE_ENVIRONMENT=1
MOZ_ARG_DISABLE_BOOL(compile-environment,
[ --disable-compile-environment
- Disable compiler/library checks.],
+ Disable compiler/library checks.],
COMPILE_ENVIRONMENT= )
AC_SUBST(COMPILE_ENVIRONMENT)
MOZ_ARG_WITH_STRING(l10n-base,
-[ --with-l10n-base=DIR path to l10n repositories],
+[ --with-l10n-base=DIR path to l10n repositories],
L10NBASEDIR=$withval)
if test ! -z "$L10NBASEDIR"; then
if test "$L10NBASEDIR" = "yes" -o "$L10NBASEDIR" = "no"; then
AC_MSG_ERROR([--with-l10n-base must specify a path])
elif test -d "$L10NBASEDIR"; then
L10NBASEDIR=`cd "$L10NBASEDIR" && pwd`
else
AC_MSG_ERROR([Invalid value --with-l10n-base, $L10NBASEDIR doesn't exist])
@@ -241,37 +241,37 @@ fi
dnl ========================================================
dnl = Android uses a very custom (hacky) toolchain; we need to do this
dnl = here, so that the compiler checks can succeed
dnl ========================================================
MOZ_ARG_WITH_STRING(android-ndk,
[ --with-android-ndk=DIR
- location where the Android NDK can be found],
+ location where the Android NDK can be found],
android_ndk=$withval)
MOZ_ARG_WITH_STRING(android-toolchain,
[ --with-android-toolchain=DIR
- location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
+ location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
android_toolchain=$withval)
MOZ_ARG_WITH_STRING(android-platform,
[ --with-android-platform=DIR
- location of NDK platform dir, default NDK/build/platforms/android-5/arch-arm],
+ location of NDK platform dir, default NDK/build/platforms/android-5/arch-arm],
android_platform=$withval)
MOZ_ARG_WITH_STRING(android-sdk,
[ --with-android-sdk=DIR
- location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
+ location where the Android SDK can be found (base directory, e.g. .../android/platforms/android-6)],
android_sdk=$withval)
MOZ_ARG_WITH_STRING(android-tools,
[ --with-android-tools=DIR
- location where the Android Tools can be found (base directory, e.g. .../android/tools)],
+ location where the Android Tools can be found (base directory, e.g. .../android/tools)],
android_tools=$withval)
if test "$target" = "arm-android-eabi" ; then
if test -z "$android_ndk" ; then
AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
fi
if test -z "$android_sdk" ; then
@@ -354,22 +354,22 @@ AR_FLAGS='cr $@'
if test "$COMPILE_ENVIRONMENT"; then
dnl Do some special WinCE toolchain stuff
case "$target" in
*wince|*winmo)
MOZ_ARG_WITH_STRING(wince-sdk,
[ --with-wince-sdk=WINCE_SDK_DIR
- The path to the Windows CE SDK],
+ The path to the Windows CE SDK],
WINCE_SDK_DIR=$withval)
MOZ_ARG_WITH_STRING(ogles-sdk,
[ --with-ogles-sdk=OGLES_SDK_DIR
- The path to the OGLES SDK],
+ The path to the OGLES SDK],
OGLES_SDK_DIR=$withval)
AC_DEFINE(WINCE)
export WINCE=1
echo -----------------------------------------------------------------------------
echo Building Windows CE Shunt Library and Tool Chain
@@ -1099,17 +1099,17 @@ esac
AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
dnl ========================================================
dnl = Mac OS X SDK support
dnl ========================================================
MACOS_SDK_DIR=
NEXT_ROOT=
MOZ_ARG_WITH_STRING(macos-sdk,
-[ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)],
+[ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)],
MACOS_SDK_DIR=$withval)
dnl MACOS_SDK_DIR will be set to the SDK location whenever one is in use.
dnl NEXT_ROOT will be set and exported only if it's needed.
AC_SUBST(MACOS_SDK_DIR)
AC_SUBST(NEXT_ROOT)
if test "$MACOS_SDK_DIR"; then
@@ -4646,17 +4646,17 @@ if test -n "$LIBXUL_SDK"; then
else
LIBXUL_DIST="$MOZ_BUILD_ROOT/dist"
fi
AC_SUBST(LIBXUL_DIST)
SYSTEM_LIBXUL=
MOZ_ARG_WITH_BOOL(system-libxul,
-[ --with-system-libxul Use system installed libxul SDK],
+[ --with-system-libxul Use system installed libxul SDK],
SYSTEM_LIBXUL=1)
if test -n "$SYSTEM_LIBXUL" && test -z "$MOZ_ENABLE_LIBXUL"; then
AC_MSG_ERROR([--with-system-libxul needs --with-libxul-sdk])
fi
dnl ========================================================
dnl = If NSPR was not detected in the system,
@@ -4735,17 +4735,17 @@ AC_SUBST(MOZ_LIBEVENT_INCLUDES)
AC_SUBST(MOZ_LIBEVENT_LIBS)
dnl ========================================================
dnl = If NSS was not detected in the system,
dnl = use the one in the source tree (mozilla/security/nss)
dnl ========================================================
MOZ_ARG_WITH_BOOL(system-nss,
-[ --with-system-nss Use system installed NSS],
+[ --with-system-nss Use system installed NSS],
_USE_SYSTEM_NSS=1 )
if test -n "$_USE_SYSTEM_NSS"; then
AM_PATH_NSS(3.12.6, [MOZ_NATIVE_NSS=1], [MOZ_NATIVE_NSS=])
fi
if test -n "$MOZ_NATIVE_NSS"; then
NSS_LIBS="$NSS_LIBS -lcrmf"
@@ -4930,44 +4930,47 @@ if test "${PNG_DIR}" -a -d "${PNG_DIR}"
PNG_LIBS="-L${PNG_DIR}/lib ${PNG_LIBS}"
fi
fi # SKIP_LIBRARY_CHECKS
dnl system HunSpell Support
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(system-hunspell,
-[ --enable-system-hunspell Use system hunspell (located with pkgconfig)],
+[ --enable-system-hunspell
+ Use system hunspell (located with pkgconfig)],
SYSTEM_HUNSPELL=1 )
if test -n "$SYSTEM_HUNSPELL"; then
PKG_CHECK_MODULES(MOZ_HUNSPELL, hunspell)
fi
AC_SUBST(SYSTEM_HUNSPELL)
dnl ========================================================
dnl Java SDK support
dnl ========================================================
JAVA_INCLUDE_PATH=
MOZ_ARG_WITH_STRING(java-include-path,
-[ --with-java-include-path=dir Location of Java SDK headers],
+[ --with-java-include-path=dir
+ Location of Java SDK headers],
JAVA_INCLUDE_PATH=$withval)
JAVA_BIN_PATH=
MOZ_ARG_WITH_STRING(java-bin-path,
-[ --with-java-bin-path=dir Location of Java binaries (java, javac, jar)],
+[ --with-java-bin-path=dir
+ Location of Java binaries (java, javac, jar)],
JAVA_BIN_PATH=$withval)
dnl ========================================================
dnl Use ARM userspace kernel helpers; tell NSPR to enable
dnl their usage and use them in spidermonkey.
dnl ========================================================
MOZ_ARG_WITH_BOOL(arm-kuser,
-[ --with-arm-kuser Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
+[ --with-arm-kuser Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
USE_ARM_KUSER=1,
USE_ARM_KUSER=)
if test -n "$USE_ARM_KUSER"; then
AC_DEFINE(USE_ARM_KUSER)
fi
dnl ========================================================
dnl =
@@ -5324,17 +5327,18 @@ dnl ====================================
dnl = startup-notification support module
dnl ========================================================
if test "$MOZ_ENABLE_GTK2"
then
MOZ_ENABLE_STARTUP_NOTIFICATION=
MOZ_ARG_ENABLE_BOOL(startup-notification,
- [ --enable-startup-notification Enable startup-notification support (default: disabled) ],
+ [ --enable-startup-notification
+ Enable startup-notification support (default: disabled) ],
MOZ_ENABLE_STARTUP_NOTIFICATION=force,
MOZ_ENABLE_STARTUP_NOTIFICATION=)
if test "$MOZ_ENABLE_STARTUP_NOTIFICATION"
then
PKG_CHECK_MODULES(MOZ_STARTUP_NOTIFICATION,
libstartup-notification-1.0 >= $STARTUP_NOTIFICATION_VERSION,
[MOZ_ENABLE_STARTUP_NOTIFICATION=1], [
if test "$MOZ_ENABLE_STARTUP_NOTIFICATION" = "force"
@@ -5420,17 +5424,18 @@ MOZ_ARG_ENABLE_STRING(ui-locale,
Select the user interface locale (default: en-US)],
MOZ_UI_LOCALE=$enableval )
AC_SUBST(MOZ_UI_LOCALE)
dnl ========================================================
dnl = Trademarked Branding
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(official-branding,
-[ --enable-official-branding Enable Official mozilla.org Branding
+[ --enable-official-branding
+ Enable Official mozilla.org Branding
Do not distribute builds with
--enable-official-branding unless you have
permission to use trademarks per
http://www.mozilla.org/foundation/trademarks/ .],
[
if test -z "$MOZ_OFFICIAL_BRANDING_DIRECTORY"; then
AC_MSG_ERROR([You must specify MOZ_OFFICIAL_BRANDING_DIRECTORY to use --enable-official-branding.])
else
@@ -5440,17 +5445,17 @@ MOZ_ARG_ENABLE_BOOL(official-branding,
], MOZ_OFFICIAL_BRANDING=)
AC_SUBST(MOZ_OFFICIAL_BRANDING)
if test -n "$MOZ_OFFICIAL_BRANDING"; then
AC_DEFINE(MOZ_OFFICIAL_BRANDING)
fi
MOZ_ARG_WITH_STRING(branding,
-[ --with-branding=dir Use branding from the specified directory.],
+[ --with-branding=dir Use branding from the specified directory.],
MOZ_BRANDING_DIRECTORY=$withval)
REAL_BRANDING_DIRECTORY="${MOZ_BRANDING_DIRECTORY}"
if test -z "$REAL_BRANDING_DIRECTORY"; then
REAL_BRANDING_DIRECTORY=${MOZ_BUILD_APP}/branding/nightly
fi
if test -f "${_topsrcdir}/$REAL_BRANDING_DIRECTORY/configure.sh"; then
@@ -5458,33 +5463,34 @@ if test -f "${_topsrcdir}/$REAL_BRANDING
fi
AC_SUBST(MOZ_BRANDING_DIRECTORY)
dnl ========================================================
dnl = Distribution ID
dnl ========================================================
MOZ_ARG_WITH_STRING(distribution-id,
-[ --with-distribution-id=ID Set distribution-specific id (default=org.mozilla)],
+[ --with-distribution-id=ID
+ Set distribution-specific id (default=org.mozilla)],
[ val=`echo $withval`
MOZ_DISTRIBUTION_ID="$val"])
if test -z "$MOZ_DISTRIBUTION_ID"; then
MOZ_DISTRIBUTION_ID="org.mozilla"
fi
AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
AC_SUBST(MOZ_DISTRIBUTION_ID)
dnl ========================================================
dnl complex text support off by default
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(pango,
-[ --disable-pango Disable usage of Pango ],
+[ --disable-pango Disable usage of Pango ],
MOZ_PANGO=,
MOZ_PANGO=1)
dnl ========================================================
dnl = Pango
dnl ========================================================
if test "$MOZ_ENABLE_GTK2"
then
@@ -5627,17 +5633,17 @@ dnl ====================================
dnl = libnotify support
dnl ========================================================
if test "$MOZ_ENABLE_GTK2"
then
MOZ_ENABLE_LIBNOTIFY=1
MOZ_ARG_DISABLE_BOOL(libnotify,
- [ --disable-libnotify Disable libnotify support ],
+ [ --disable-libnotify Disable libnotify support ],
MOZ_ENABLE_LIBNOTIFY=,
MOZ_ENABLE_LIBNOTIFY=1)
if test "$MOZ_ENABLE_LIBNOTIFY"
then
AC_DEFINE(MOZ_ENABLE_LIBNOTIFY)
fi
fi
@@ -5713,17 +5719,17 @@ dnl ====================================
dnl = dbus support
dnl ========================================================
if test "$MOZ_ENABLE_GTK2" || test "$MOZ_ENABLE_QT"
then
MOZ_ENABLE_DBUS=1
MOZ_ARG_DISABLE_BOOL(dbus,
- [ --disable-dbus Disable dbus support ],
+ [ --disable-dbus Disable dbus support ],
MOZ_ENABLE_DBUS=,
MOZ_ENABLE_DBUS=1)
if test "$MOZ_ENABLE_DBUS"
then
PKG_CHECK_MODULES(MOZ_DBUS, dbus-1 >= $DBUS_VERSION)
PKG_CHECK_MODULES(MOZ_DBUS_GLIB, dbus-glib-1 >= $DBUS_VERSION)
AC_DEFINE(MOZ_ENABLE_DBUS)
@@ -5799,17 +5805,17 @@ MOZ_ARG_DISABLE_BOOL(plugins,
[ --disable-plugins Disable plugins support],
MOZ_PLUGINS=,
MOZ_PLUGINS=1)
dnl ========================================================
dnl = Disable building dbm
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(dbm,
-[ --disable-dbm Disable building dbm],
+[ --disable-dbm Disable building dbm],
NSS_DISABLE_DBM=1,
NSS_DISABLE_DBM=)
dnl bi-directional support always on
IBMBIDI=1
AC_DEFINE(IBMBIDI)
dnl ========================================================
@@ -5850,17 +5856,17 @@ dnl ====================================
if test "$MOZ_JSLOADER"; then
AC_DEFINE(MOZ_JSLOADER)
fi
dnl ========================================================
dnl Disable printing
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(printing,
-[ --disable-printing Disable printing support],
+[ --disable-printing Disable printing support],
NS_PRINTING=,
NS_PRINTING=1 )
if test "$MOZ_WIDGET_TOOLKIT" = "qt"; then
AC_MSG_WARN([Printing does not work with Qt at this time. Omitting printing support.])
NS_PRINTING=
fi
@@ -5896,17 +5902,18 @@ MOZ_ARG_ENABLE_BOOL(plaintext-editor-onl
MOZ_PLAINTEXT_EDITOR_ONLY= )
dnl Note the #define is MOZILLA, not MOZ, for compat with the Mac build.
AC_SUBST(MOZ_PLAINTEXT_EDITOR_ONLY)
dnl ========================================================
dnl = Disable Fast Load
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(xpcom-fastload,
-[ --disable-xpcom-fastload Disable XPCOM fastload support],
+[ --disable-xpcom-fastload
+ Disable XPCOM fastload support],
MOZ_NO_FAST_LOAD=1,
MOZ_NO_FAST_LOAD=)
AC_SUBST(MOZ_NO_FAST_LOAD)
if test -n "$MOZ_NO_FAST_LOAD"; then
AC_DEFINE(MOZ_NO_FAST_LOAD)
fi
@@ -6065,30 +6072,48 @@ case "${target}" in
esac
MOZ_ARG_ENABLE_BOOL(javaxpcom,
[ --enable-javaxpcom
Enable Java-XPCOM bridge],
MOZ_JAVAXPCOM=1,
MOZ_JAVAXPCOM= )
+case "$host_os" in
+ cygwin*|msvc*|mks*)
+ if test -n "$JAVA_HOME"; then
+ JAVA_HOME=`cygpath -u \`cygpath -m -s "$JAVA_HOME"\``
+ fi
+ ;;
+ *mingw*)
+ if test -n "$JAVA_HOME"; then
+ JAVA_HOME=`cd "$JAVA_HOME" && pwd`
+ fi
+ ;;
+esac
+
+if test -n "${JAVA_BIN_PATH}"; then
+ dnl Look for javac and jar in the specified path.
+ JAVA_PATH="$JAVA_BIN_PATH"
+else
+ dnl No path specified, so look for javac and jar in $JAVA_HOME & $PATH.
+ JAVA_PATH="$JAVA_HOME/bin:$PATH"
+fi
+
+MOZ_PATH_PROG(JAVA, java, :, [$JAVA_PATH])
+MOZ_PATH_PROG(JAVAC, javac, :, [$JAVA_PATH])
+MOZ_PATH_PROG(JAR, jar, :, [$JAVA_PATH])
+
+if test -n "${JAVA_BIN_PATH}" || test "$OS_TARGET" = Android; then
+ if test -z "$JAVA" || test "$JAVA" = ":" || test -z "$JAVAC" || test "$JAVAC" = ":" || test -z "$JAR" || test "$JAR" = ":"; then
+ AC_MSG_ERROR([The programs java, javac and jar were not found. Set \$JAVA_HOME to your java sdk directory or use --with-java-bin-path={java-bin-dir}])
+ fi
+fi
+
if test -n "${MOZ_JAVAXPCOM}"; then
- case "$host_os" in
- cygwin*|msvc*|mks*)
- if test -n "$JAVA_HOME"; then
- JAVA_HOME=`cygpath -u \`cygpath -m -s "$JAVA_HOME"\``
- fi
- ;;
- *mingw*)
- if test -n "$JAVA_HOME"; then
- JAVA_HOME=`cd "$JAVA_HOME" && pwd`
- fi
- ;;
- esac
-
if test -n "${JAVA_INCLUDE_PATH}"; then
dnl Make sure jni.h exists in the given include path.
if test ! -f "$JAVA_INCLUDE_PATH/jni.h"; then
AC_MSG_ERROR([jni.h was not found in given include path $JAVA_INCLUDE_PATH.])
fi
else
case "$target_os" in
darwin*)
@@ -6099,31 +6124,16 @@ if test -n "${MOZ_JAVAXPCOM}"; then
dnl Try $JAVA_HOME
JAVA_INCLUDE_PATH="$JAVA_HOME/include"
;;
esac
if test ! -f "$JAVA_INCLUDE_PATH/jni.h"; then
AC_MSG_ERROR([The header jni.h was not found. Set \$JAVA_HOME to your java sdk directory, use --with-java-bin-path={java-bin-dir}, or reconfigure with --disable-javaxpcom.])
fi
fi
-
- if test -n "${JAVA_BIN_PATH}"; then
- dnl Look for javac and jar in the specified path.
- JAVA_PATH="$JAVA_BIN_PATH"
- else
- dnl No path specified, so look for javac and jar in $JAVA_HOME & $PATH.
- JAVA_PATH="$JAVA_HOME/bin:$PATH"
- fi
-
- MOZ_PATH_PROG(JAVA, java, :, [$JAVA_PATH])
- MOZ_PATH_PROG(JAVAC, javac, :, [$JAVA_PATH])
- MOZ_PATH_PROG(JAR, jar, :, [$JAVA_PATH])
- if test -z "$JAVA" || test "$JAVA" = ":" || test -z "$JAVAC" || test "$JAVAC" = ":" || test -z "$JAR" || test "$JAR" = ":"; then
- AC_MSG_ERROR([The programs java, javac and jar were not found. Set \$JAVA_HOME to your java sdk directory, use --with-java-bin-path={java-bin-dir}, or reconfigure with --disable-javaxpcom.])
- fi
fi
dnl ========================================================
dnl = Breakpad crash reporting (on by default on supported platforms)
dnl ========================================================
case $target in
i?86-*-mingw*)
@@ -6136,17 +6146,17 @@ i?86-*-linux*|x86_64-*-linux*|arm-*-linu
MOZ_CRASHREPORTER=1
;;
*solaris*)
MOZ_CRASHREPORTER=1
;;
esac
MOZ_ARG_DISABLE_BOOL(crashreporter,
-[ --disable-crashreporter Disable breakpad crash reporting],
+[ --disable-crashreporter Disable breakpad crash reporting],
MOZ_CRASHREPORTER=,
MOZ_CRASHREPORTER=1)
if test -n "$MOZ_CRASHREPORTER"; then
AC_DEFINE(MOZ_CRASHREPORTER)
if (test "$OS_ARCH" = "Linux" || test "$OS_ARCH" = "SunOS") && \
test -z "$SKIP_LIBRARY_CHECKS"; then
@@ -6154,17 +6164,18 @@ if test -n "$MOZ_CRASHREPORTER"; then
AC_SUBST(MOZ_GTHREAD_CFLAGS)
AC_SUBST(MOZ_GTHREAD_LIBS)
AC_CHECK_HEADERS([curl/curl.h], [], [AC_MSG_ERROR([Couldn't find curl/curl.h which is required for the crash reporter. Use --disable-crashreporter to disable the crash reporter.])])
fi
fi
MOZ_ARG_WITH_STRING(crashreporter-enable-percent,
-[ --with-crashreporter-enable-percent=NN Enable sending crash reports by default on NN% of users. (default=100)],
+[ --with-crashreporter-enable-percent=NN
+ Enable sending crash reports by default on NN% of users. (default=100)],
[ val=`echo $withval | sed 's/[^0-9]//g'`
MOZ_CRASHREPORTER_ENABLE_PERCENT="$val"])
if test -z "$MOZ_CRASHREPORTER_ENABLE_PERCENT"; then
MOZ_CRASHREPORTER_ENABLE_PERCENT=100
fi
AC_DEFINE_UNQUOTED(MOZ_CRASHREPORTER_ENABLE_PERCENT, $MOZ_CRASHREPORTER_ENABLE_PERCENT)
@@ -6357,44 +6368,44 @@ MOZ_ARG_DISABLE_BOOL(mathml,
if test "$MOZ_MATHML"; then
AC_DEFINE(MOZ_MATHML)
fi
dnl ========================================================
dnl SVG
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(svg,
-[ --disable-svg Disable SVG support],
+[ --disable-svg Disable SVG support],
MOZ_SVG=,
MOZ_SVG=1 )
if test -n "$MOZ_SVG"; then
AC_DEFINE(MOZ_SVG)
fi
dnl ========================================================
dnl SMIL
dnl ========================================================
MOZ_SMIL=1
MOZ_ARG_DISABLE_BOOL(smil,
-[ --disable-smil Disable SMIL animation support],
+[ --disable-smil Disable SMIL animation support],
MOZ_SMIL=,
MOZ_SMIL=1 )
# Automatically disable SMIL if SVG is disabled
if test -z "$MOZ_SVG"; then
MOZ_SMIL=
fi
if test -n "$MOZ_SMIL"; then
AC_DEFINE(MOZ_SMIL)
fi
dnl ========================================================
dnl Build Freetype in the tree
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(tree-freetype,
-[ --enable-tree-freetype Enable Tree FreeType],
+[ --enable-tree-freetype Enable Tree FreeType],
MOZ_TREE_FREETYPE=1,
MOZ_TREE_FREETYPE= )
if test -n "$MOZ_TREE_FREETYPE"; then
AC_DEFINE(MOZ_TREE_FREETYPE)
AC_SUBST(MOZ_TREE_FREETYPE)
MOZ_ENABLE_CAIRO_FT=1
FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
FT2_CFLAGS='-I$(topsrcdir)/modules/freetype2/include'
@@ -6459,28 +6470,28 @@ MOZ_ARG_DISABLE_BOOL(updater,
[ --disable-updater Disable building of updater],
MOZ_UPDATER=,
MOZ_UPDATER=1 )
AC_SUBST(MOZ_UPDATER)
# app update channel is 'default' when not supplied.
MOZ_ARG_ENABLE_STRING([update-channel],
[ --enable-update-channel=CHANNEL
- Select application update channel (default=default)],
+ Select application update channel (default=default)],
MOZ_UPDATE_CHANNEL=`echo $enableval | tr A-Z a-z`)
if test -z "$MOZ_UPDATE_CHANNEL"; then
MOZ_UPDATE_CHANNEL=default
fi
AC_DEFINE_UNQUOTED(MOZ_UPDATE_CHANNEL, $MOZ_UPDATE_CHANNEL)
# tools/update-packaging is not checked out by default.
MOZ_ARG_ENABLE_BOOL(update-packaging,
[ --enable-update-packaging
- Enable tools/update-packaging],
+ Enable tools/update-packaging],
MOZ_UPDATE_PACKAGING=1,
MOZ_UPDATE_PACKAGING= )
AC_SUBST(MOZ_UPDATE_PACKAGING)
dnl ========================================================
dnl ActiveX
dnl ========================================================
@@ -6539,17 +6550,17 @@ MOZ_ARG_DISABLE_BOOL(tests,
ENABLE_TESTS=,
ENABLE_TESTS=1 )
dnl ========================================================
dnl parental controls (for Windows Vista)
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(parental-controls,
[ --disable-parental-controls
- Do not build parental controls],
+ Do not build parental controls],
MOZ_DISABLE_PARENTAL_CONTROLS=1,
MOZ_DISABLE_PARENTAL_CONTROLS=)
if test -n "$MOZ_DISABLE_PARENTAL_CONTROLS"; then
AC_DEFINE(MOZ_DISABLE_PARENTAL_CONTROLS)
fi
AC_SUBST(MOZ_DISABLE_PARENTAL_CONTROLS)
@@ -6559,17 +6570,17 @@ dnl = Module specific options
dnl =
dnl ========================================================
MOZ_ARG_HEADER(Individual module options)
dnl ========================================================
dnl = Disable feed handling components
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(feeds,
-[ --disable-feeds Disable feed handling and processing components],
+[ --disable-feeds Disable feed handling and processing components],
MOZ_FEEDS=,
MOZ_FEEDS=1 )
if test -n "$MOZ_FEEDS"; then
AC_DEFINE(MOZ_FEEDS)
else
if test "$MOZ_BUILD_APP" = "browser"; then
AC_MSG_ERROR([Cannot build Firefox with --disable-feeds.])
fi
@@ -6705,67 +6716,67 @@ if test -n "$MOZ_HELP_VIEWER"; then
dnl Do this if defined in confvars.sh
AC_DEFINE(MOZ_HELP_VIEWER)
fi
dnl ========================================================
dnl = Enable safe browsing (anti-phishing)
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(safe-browsing,
-[ --enable-safe-browsing Enable safe browsing (anti-phishing) implementation],
+[ --enable-safe-browsing Enable safe browsing (anti-phishing) implementation],
MOZ_SAFE_BROWSING=1,
MOZ_SAFE_BROWSING= )
if test -n "$MOZ_SAFE_BROWSING"; then
AC_DEFINE(MOZ_SAFE_BROWSING)
fi
AC_SUBST(MOZ_SAFE_BROWSING)
dnl ========================================================
dnl = Enable faststart component
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(faststart,
-[ --enable-faststart Enable the faststart component],
+[ --enable-faststart Enable the faststart component],
MOZ_FASTSTART=1,
MOZ_FASTSTART= )
if test -n "$MOZ_FASTSTART"; then
AC_DEFINE(MOZ_FASTSTART)
fi
AC_SUBST(MOZ_FASTSTART)
dnl ========================================================
dnl = Enable url-classifier
dnl ========================================================
dnl Implicitly enabled by default if building with safe-browsing
if test -n "$MOZ_SAFE_BROWSING"; then
MOZ_URL_CLASSIFIER=1
fi
MOZ_ARG_ENABLE_BOOL(url-classifier,
-[ --enable-url-classifier Enable url classifier module],
+[ --enable-url-classifier Enable url classifier module],
MOZ_URL_CLASSIFIER=1,
MOZ_URL_CLASSIFIER= )
if test -n "$MOZ_URL_CLASSIFIER"; then
AC_DEFINE(MOZ_URL_CLASSIFIER)
fi
AC_SUBST(MOZ_URL_CLASSIFIER)
dnl ========================================================
dnl = Disable zipwriter
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(zipwriter,
-[ --disable-zipwriter Disable zipwriter component],
+[ --disable-zipwriter Disable zipwriter component],
MOZ_ZIPWRITER=,
MOZ_ZIPWRITER=1 )
AC_SUBST(MOZ_ZIPWRITER)
dnl ========================================================
dnl = Disable libconic
dnl ========================================================
MOZ_ENABLE_LIBCONIC=1
MOZ_ARG_DISABLE_BOOL(libconic,
-[ --disable-libconic Disable libconic],
+[ --disable-libconic Disable libconic],
MOZ_ENABLE_LIBCONIC=,
MOZ_ENABLE_LIBCONIC=1 )
if test -n "$MOZ_ENABLE_LIBCONIC"; then
PKG_CHECK_MODULES(LIBCONIC, conic,
MOZ_ENABLE_LIBCONIC=1,
MOZ_ENABLE_LIBCONIC=)
fi
@@ -6780,17 +6791,17 @@ AC_SUBST(LIBCONIC_LIBS)
dnl ========================================================
dnl = Maemo checks
dnl ========================================================
MAEMO_SDK_TARGET_VER=-1
MOZ_ARG_WITH_STRING(maemo-version,
[ --with-maemo-version=MAEMO_SDK_TARGET_VER
- Maemo SDK Version],
+ Maemo SDK Version],
MAEMO_SDK_TARGET_VER=$withval)
case "$MAEMO_SDK_TARGET_VER" in
5)
MOZ_PLATFORM_MAEMO=5
;;
6)
@@ -6867,17 +6878,17 @@ if test $MOZ_PLATFORM_MAEMO; then
AC_SUBST(MOZ_PLATFORM_MAEMO_LIBS)
AC_SUBST(MOZ_PLATFORM_MAEMO_CFLAGS)
fi
dnl ========================================================
dnl = Enable building the Thumb2 instruction set
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(thumb2,
- [ --enable-thumb2 Enable Thumb2 instruction set],
+ [ --enable-thumb2 Enable Thumb2 instruction set],
MOZ_THUMB2=1,
MOZ_THUMB2=)
if test -n "$MOZ_THUMB2"; then
case "$target_cpu" in
arm*)
if test "$GNU_CC"; then
CFLAGS="$CFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
@@ -6892,17 +6903,17 @@ if test -n "$MOZ_THUMB2"; then
;;
esac
fi
dnl ========================================================
dnl = faststripe theme
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(faststripe,
-[ --enable-faststripe Use faststripe theme],
+[ --enable-faststripe Use faststripe theme],
MOZ_THEME_FASTSTRIPE=1,
MOZ_THEME_FASTSTRIPE= )
AC_SUBST(MOZ_THEME_FASTSTRIPE)
dnl ========================================================
dnl =
dnl = Feature options that require extra sources to be pulled
dnl =
@@ -6956,18 +6967,18 @@ MOZ_ARG_ENABLE_STRING(debug,
else
MOZ_DEBUG=
fi ],
MOZ_DEBUG=)
MOZ_DEBUG_ENABLE_DEFS="-DDEBUG -D_DEBUG"
MOZ_ARG_WITH_STRING(debug-label,
[ --with-debug-label=LABELS
- Define DEBUG_<value> for each comma-separated
- value given.],
+ Define DEBUG_<value> for each comma-separated
+ value given.],
[ for option in `echo $withval | sed 's/,/ /g'`; do
MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${option}"
done])
case "${target_os}" in
beos*)
MOZ_DEBUG_ENABLE_DEFS="$MOZ_DEBUG_ENABLE_DEFS -DDEBUG_${USER}"
;;
@@ -6996,17 +7007,18 @@ if test -n "$MOZ_DEBUG"; then
fi
CFLAGS=$_SAVE_CFLAGS
fi
dnl ========================================================
dnl enable mobile optimizations
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(mobile-optimize,
-[ --enable-mobile-optimize Enable mobile optimizations],
+[ --enable-mobile-optimize
+ Enable mobile optimizations],
MOZ_GFX_OPTIMIZE_MOBILE=1)
AC_SUBST(MOZ_GFX_OPTIMIZE_MOBILE)
if test "$MOZ_GFX_OPTIMIZE_MOBILE"; then
AC_DEFINE(MOZ_GFX_OPTIMIZE_MOBILE)
fi
@@ -7062,18 +7074,18 @@ MOZ_ARG_ENABLE_STRING(debugger-info-modu
AC_MSG_WARN([--enable-debugger-info-modules is deprecated, use --enable-debug-symbols instead])
MOZ_DEBUG_SYMBOLS=1
fi ])
dnl ========================================================
dnl = Enable generation of debug symbols
dnl ========================================================
MOZ_ARG_ENABLE_STRING(debug-symbols,
-[ --enable-debug-symbols[=DBG] Enable debugging symbols
- (using compiler flags DBG)],
+[ --enable-debug-symbols[=DBG]
+ Enable debugging symbols (using compiler flags DBG)],
[ if test "$enableval" != "no"; then
MOZ_DEBUG_SYMBOLS=1
if test -n "$enableval" -a "$enableval" != "yes"; then
if test -z "$_MOZ_DEBUG_FLAGS_SET"; then
MOZ_DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
else
AC_MSG_ERROR([--enable-debug-symbols flags cannot be used with --enable-debug flags])
fi
@@ -7084,17 +7096,18 @@ if test -n "$MOZ_DEBUG" -o -n "$MOZ_DEBU
AC_DEFINE(MOZ_DEBUG_SYMBOLS)
export MOZ_DEBUG_SYMBOLS
fi
dnl ========================================================
dnl = Disable any treating of compile warnings as errors
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(warnings-as-errors,
-[ --disable-warnings-as-errors Disable treating of warnings as errors],
+[ --disable-warnings-as-errors
+ Disable treating of warnings as errors],
MOZ_DISABLE_WARNINGS_AS_ERRORS=1,
MOZ_DISABLE_WARNINGS_AS_ERRORS= )
if test "$MOZ_DISABLE_WARNINGS_AS_ERRORS"; then
WARNINGS_AS_ERRORS=''
fi
dnl ========================================================
dnl = Disable runtime logging checks
@@ -7209,29 +7222,34 @@ if test "$MOZ_MEMORY"; then
AC_MSG_ERROR([When building jemalloc, set WIN32_CRT_SRC_DIR to the path to the Visual C++ CRT source (usually VCINSTALLDIR\crt\src, but VCINSTALLDIR is not set, so I can't autodetect it for you).])
else
WIN32_CRT_SRC_DIR="$VCINSTALLDIR\crt\src"
fi
fi
dnl cpu check
case "${target_cpu}" in
i*86)
- _WIN32_CRT_CPU=intel
+ MOZ_CRT_CPU_ARCH=intel
+ ;;
+ x86_64)
+ MOZ_CRT_CPU_ARCH=amd64
;;
*)
AC_MSG_ERROR([--enable-jemalloc not supported on ${target}])
;;
esac
+ AC_SUBST(MOZ_CRT_CPU_ARCH)
+
if test ! -d "$WIN32_CRT_SRC_DIR"; then
AC_MSG_ERROR([Invalid Win32 CRT source directory: ${WIN32_CRT_SRC_DIR}])
fi
WIN32_CRT_SRC_DIR=`cd "$WIN32_CRT_SRC_DIR" && pwd -W`
_objdir_win=`pwd -W`
- WIN32_CUSTOM_CRT_DIR="$_objdir_win/memory/jemalloc/crtsrc/build/$_WIN32_CRT_CPU"
+ WIN32_CUSTOM_CRT_DIR="$_objdir_win/memory/jemalloc/crtsrc/build/$MOZ_CRT_CPU_ARCH"
MOZ_MEMORY_LDFLAGS="-MANIFEST:NO -LIBPATH:\"$WIN32_CUSTOM_CRT_DIR\" -NODEFAULTLIB:msvcrt -NODEFAULTLIB:msvcrtd -NODEFAULTLIB:msvcprt -NODEFAULTLIB:msvcprtd -DEFAULTLIB:mozcrt19 -DEFAULTLIB:mozcpp19"
dnl Also pass this to NSPR/NSS
DLLFLAGS="$DLLFLAGS $MOZ_MEMORY_LDFLAGS"
export DLLFLAGS
;;
*-*wince)
AC_DEFINE(MOZ_MEMORY_WINCE)
AC_DEFINE(MOZ_MEMORY_WINDOWS)
@@ -7297,17 +7315,17 @@ MOZ_ARG_ENABLE_BOOL(tracevis,
if test -n "$MOZ_TRACEVIS"; then
AC_DEFINE(MOZ_TRACEVIS)
fi
dnl ========================================================
dnl = Use GCTimer
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(gctimer,
-[ --enable-gctimer Enable GC timer (default=no)],
+[ --enable-gctimer Enable GC timer (default=no)],
MOZ_GCTIMER=1,
MOZ_GCTIMER= )
if test -n "$MOZ_GCTIMER"; then
AC_DEFINE(MOZ_GCTIMER)
fi
dnl ========================================================
dnl = Use Valgrind
@@ -7366,30 +7384,30 @@ MOZ_ARG_ENABLE_BOOL(vtune,
if test -n "$MOZ_VTUNE"; then
AC_DEFINE(MOZ_VTUNE)
fi
dnl ========================================================
dnl Zealous JavaScript GC
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(gczeal,
-[ --enable-gczeal Enable zealous JavaScript GCing],
+[ --enable-gczeal Enable zealous JavaScript GCing],
JS_GC_ZEAL=1,
JS_GC_ZEAL= )
if test -n "$JS_GC_ZEAL"; then
AC_DEFINE(JS_GC_ZEAL)
fi
dnl ========================================================
dnl = Enable static checking using gcc-dehydra
dnl ========================================================
MOZ_ARG_WITH_STRING(static-checking,
[ --with-static-checking=path/to/gcc_dehydra.so
- Enable static checking of code using GCC-dehydra],
+ Enable static checking of code using GCC-dehydra],
DEHYDRA_PATH=$withval,
DEHYDRA_PATH= )
if test -n "$DEHYDRA_PATH"; then
if test ! -f "$DEHYDRA_PATH"; then
AC_MSG_ERROR([The dehydra plugin is not at the specified path.])
fi
AC_DEFINE(NS_STATIC_CHECKING)
@@ -7441,17 +7459,17 @@ if test -n "$MOZ_TIMELINE"; then
fi
dnl ========================================================
dnl = Enable NS_FUNCTION_TIMER, which provides Function
dnl = timing for identifying code bottlenecks
dnl = NS_FUNCTION_TIMER is off by default.
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(functiontimer,
-[ --enable-functiontimer Enable NS_FUNCTION_TIMER ],
+[ --enable-functiontimer Enable NS_FUNCTION_TIMER ],
NS_FUNCTION_TIMER=1,
NS_FUNCTION_TIMER= )
if test -n "$NS_FUNCTION_TIMER"; then
AC_DEFINE(NS_FUNCTION_TIMER)
fi
dnl ========================================================
dnl Turn on reflow counting
@@ -7478,17 +7496,17 @@ if test -n "$_ENABLE_CODESIGHS"; then
AC_MSG_ERROR([Codesighs directory $srcdir/tools/codesighs required.])
fi
fi
dnl ========================================================
dnl = Support for Quantify (Windows)
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(quantify,
-[ --enable-quantify Enable Quantify support (Windows only) ],
+[ --enable-quantify Enable Quantify support (Windows only) ],
MOZ_QUANTIFY=1,
MOZ_QUANTIFY= )
dnl ========================================================
dnl = Support for demangling undefined symbols
dnl ========================================================
if test -z "$SKIP_LIBRARY_CHECKS"; then
AC_LANG_SAVE
@@ -7664,17 +7682,17 @@ dnl Profile guided optimization
dnl ========================================================
dnl Test for profiling options
dnl Under gcc 3.3, use -fprofile-arcs/-fbranch-probabilities
dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use
dnl Provide a switch to disable PGO even when called via profiledbuild.
MOZ_ARG_DISABLE_BOOL(profile-guided-optimization,
[ --disable-profile-guided-optimization
- Don't build with PGO even if called via make profiledbuild],
+ Don't build with PGO even if called via make profiledbuild],
MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE=1,
MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE=)
AC_SUBST(MOZ_PROFILE_GUIDED_OPTIMIZE_DISABLE)
_SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fprofile-generate -fprofile-correction"
@@ -8124,17 +8142,17 @@ AC_SUBST(HOST_LIBIDL_LIBS)
dnl ========================================================
dnl Check for cairo
dnl ========================================================
MOZ_CAIRO_CFLAGS='-I$(LIBXUL_DIST)/include/cairo'
MOZ_TREE_CAIRO=1
MOZ_ARG_ENABLE_BOOL(system-cairo,
-[ --enable-system-cairo Use system cairo (located with pkgconfig)],
+[ --enable-system-cairo Use system cairo (located with pkgconfig)],
MOZ_TREE_CAIRO=,
MOZ_TREE_CAIRO=1 )
# Check for headers defining standard int types.
AC_CHECK_HEADERS(stdint.h inttypes.h sys/int_types.h)
if test "$MOZ_TREE_CAIRO"; then
AC_DEFINE(MOZ_TREE_CAIRO)
@@ -8311,17 +8329,18 @@ fi
AC_SUBST(MOZ_XUL)
dnl ========================================================
dnl disable profile locking
dnl do no use this in applications that can have more than
dnl one process accessing the profile directory.
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(profilelocking,
-[ --disable-profilelocking Disable profile locking],
+[ --disable-profilelocking
+ Disable profile locking],
MOZ_PROFILELOCKING=,
MOZ_PROFILELOCKING=1 )
if test "$MOZ_PROFILELOCKING"; then
AC_DEFINE(MOZ_PROFILELOCKING)
fi
dnl ========================================================
dnl disable rdf services
@@ -8379,17 +8398,17 @@ AC_SUBST(NECKO_DISK_CACHE)
if test "$NECKO_DISK_CACHE"; then
AC_DEFINE(NECKO_DISK_CACHE)
fi
dnl
dnl option to disable necko's wifi scanner
dnl
MOZ_ARG_DISABLE_BOOL(necko-wifi,
-[ --disable-necko-wifi Disable necko wifi scanner],
+[ --disable-necko-wifi Disable necko wifi scanner],
NECKO_WIFI=,
NECKO_WIFI=1
)
if test "$OS_ARCH" = "OS2"; then
dnl OS/2 implementation of Necko-WiFi support will be added in bug 506566
NECKO_WIFI=
fi
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1346,22 +1346,16 @@ public:
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
/**
* Return true if aURI is a local file URI (i.e. file://).
*/
static PRBool URIIsLocalFile(nsIURI *aURI);
/**
- * If aContent is an HTML element with a DOM level 0 'name', then
- * return the name. Otherwise return null.
- */
- static nsIAtom* IsNamedItem(Element* aElement);
-
- /**
* Get the application manifest URI for this document. The manifest URI
* is specified in the manifest= attribute of the root element of the
* document.
*
* @param aDocument The document that lists the manifest.
* @param aURI The manifest URI.
*/
static void GetOfflineAppManifest(nsIDocument *aDocument, nsIURI **aURI);
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -66,18 +66,18 @@ enum nsLinkState {
eLinkState_Unknown = 0,
eLinkState_Unvisited = 1,
eLinkState_Visited = 2,
eLinkState_NotLink = 3
};
// IID for the nsIContent interface
#define NS_ICONTENT_IID \
-{ 0x9e3b1a15, 0x72d5, 0x4e4f, \
- { 0x8f, 0x4b, 0x75, 0xde, 0x07, 0x9c, 0x16, 0xdc } }
+{ 0x1450010b, 0xcdca, 0x451c, \
+ { 0xba, 0xdc, 0x07, 0x90, 0x89, 0x7b, 0xce, 0xb8 } }
/**
* A node of content in a document's content model. This interface
* is supported by all content objects.
*/
class nsIContent : public nsINode {
public:
#ifdef MOZILLA_INTERNAL_API
@@ -773,17 +773,22 @@ public:
// PRInt32. We should really use PRUint32 instead.
virtual PRInt32 IntrinsicState() const;
/**
* Get the ID of this content node (the atom corresponding to the
* value of the null-namespace attribute whose name is given by
* GetIDAttributeName(). This may be null if there is no ID.
*/
- virtual nsIAtom* GetID() const = 0;
+ nsIAtom* GetID() const {
+ if (HasFlag(NODE_HAS_ID)) {
+ return DoGetID();
+ }
+ return nsnull;
+ }
/**
* Get the class list of this content node (this corresponds to the
* value of the null-namespace attribute whose name is given by
* GetClassAttributeName()). This may be null if there are no
* classes, but that's not guaranteed.
*/
const nsAttrValue* GetClasses() const {
@@ -910,16 +915,23 @@ public:
nsAString& aNamespaceURI) const;
nsIAtom* LookupPrefix(const nsAString& aNamespaceURI);
PRBool IsEqual(nsIContent *aOther);
virtual PRBool IsEqualNode(nsINode* aOther);
+protected:
+ /**
+ * Hook for implementing GetID. This is guaranteed to only be
+ * called if the NODE_HAS_ID flag is set.
+ */
+ virtual nsIAtom* DoGetID() const = 0;
+
private:
/**
* Hook for implementing GetClasses. This is guaranteed to only be
* called if the NODE_MAY_HAVE_CLASS flag is set.
*/
virtual const nsAttrValue* DoGetClasses() const = 0;
/**
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -111,18 +111,18 @@ class Loader;
namespace dom {
class Link;
class Element;
} // namespace dom
} // namespace mozilla
#define NS_IDOCUMENT_IID \
-{ 0xdf6c0752, 0xe780, 0x4576, \
- { 0x95, 0x3c, 0x7e, 0xf1, 0xde, 0x9f, 0xd7, 0xf0 } }
+{ 0x3ee6a14b, 0x83b5, 0x4629, \
+ { 0x96, 0x9b, 0xe9, 0x84, 0x7c, 0x57, 0x24, 0x3c } }
// Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
// Document states
// RTL locale: specific to the XUL localedir attribute
#define NS_DOCUMENT_STATE_RTL_LOCALE (1 << 0)
@@ -665,16 +665,27 @@ public:
return mRemovedFromDocShell ? GetInnerWindowInternal() : mWindow;
}
/**
* Get the script loader for this document
*/
virtual nsScriptLoader* ScriptLoader() = 0;
+ /**
+ * Add/Remove an element to the document's id and name hashes
+ */
+ virtual void AddToIdTable(mozilla::dom::Element* aElement, nsIAtom* aId) = 0;
+ virtual void RemoveFromIdTable(mozilla::dom::Element* aElement,
+ nsIAtom* aId) = 0;
+ virtual void AddToNameTable(mozilla::dom::Element* aElement,
+ nsIAtom* aName) = 0;
+ virtual void RemoveFromNameTable(mozilla::dom::Element* aElement,
+ nsIAtom* aName) = 0;
+
//----------------------------------------------------------------------
// Document notification API's
/**
* Add a new observer of document change notifications. Whenever
* content is changed, appended, inserted or removed the observers are
* informed. An observer that is already observing the document must
@@ -797,16 +808,20 @@ public:
virtual void GetXMLDeclaration(nsAString& aVersion,
nsAString& aEncoding,
nsAString& Standalone) = 0;
PRBool IsHTML() const
{
return mIsRegularHTML;
}
+ PRBool IsXUL() const
+ {
+ return mIsXUL;
+ }
virtual PRBool IsScriptEnabled() = 0;
virtual nsresult AddXMLEventsContent(nsIContent * aXMLEventsElement) = 0;
/**
* Create an element with the specified name, prefix and namespace ID.
* If aDocumentDefaultType is true we create an element of the default type
@@ -1364,18 +1379,17 @@ public:
virtual void SetChangeScrollPosWhenScrollingToRef(PRBool aValue) = 0;
/**
* This method is similar to GetElementById() from nsIDOMDocument but it
* returns a mozilla::dom::Element instead of a nsIDOMElement.
* It prevents converting nsIDOMElement to mozill:dom::Element which is
* already converted from mozilla::dom::Element.
*/
- virtual mozilla::dom::Element* GetElementById(const nsAString& aElementId,
- nsresult* aResult) = 0;
+ virtual mozilla::dom::Element* GetElementById(const nsAString& aElementId) = 0;
protected:
~nsIDocument()
{
// XXX The cleanup of mNodeInfoManager (calling DropDocumentReference and
// releasing it) happens in the nsDocument destructor. We'd prefer to
// do it here but nsNodeInfoManager is a concrete class that we don't
// want to expose to users of the nsIDocument API outside of Gecko.
@@ -1457,16 +1471,17 @@ protected:
// basically be true only for documents that exist in newly-opened windows or
// documents created to satisfy a GetDocument() on a window when there's no
// document in it.
PRPackedBool mIsInitialDocumentInWindow;
PRPackedBool mShellIsHidden;
PRPackedBool mIsRegularHTML;
+ PRPackedBool mIsXUL;
// True if we're loaded as data and therefor has any dangerous stuff, such
// as scripts and plugins, disabled.
PRPackedBool mLoadedAsData;
// If true, whoever is creating the document has gotten it to the
// point where it's safe to start layout on it.
PRPackedBool mMayStartLayout;
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -112,19 +112,20 @@ enum {
// in the document and therefore should get bindings attached.
NODE_FORCE_XBL_BINDINGS = 0x00000040U,
// Whether a binding manager may have a pointer to this
NODE_MAY_BE_IN_BINDING_MNGR = 0x00000080U,
NODE_IS_EDITABLE = 0x00000100U,
- // Optimizations to quickly check whether element may have ID, class or style
- // attributes. Not all element implementations may use these!
- NODE_MAY_HAVE_ID = 0x00000200U,
+ // Set to true if the element has a non-empty id attribute. This can in rare
+ // cases lie for nsXMLElement, such as when the node has been moved between
+ // documents with different id mappings.
+ NODE_HAS_ID = 0x00000200U,
// For all Element nodes, NODE_MAY_HAVE_CLASS is guaranteed to be set if the
// node in fact has a class, but may be set even if it doesn't.
NODE_MAY_HAVE_CLASS = 0x00000400U,
NODE_MAY_HAVE_STYLE = 0x00000800U,
NODE_IS_INSERTION_PARENT = 0x00001000U,
// Node has an :empty or :-moz-only-whitespace selector
@@ -165,19 +166,25 @@ enum {
// At least one descendant in the flattened tree has NODE_NEEDS_FRAME set.
// This should be set on every node on the flattened tree path between the
// node(s) with NODE_NEEDS_FRAME and the root content.
NODE_DESCENDANTS_NEED_FRAMES = 0x00100000U,
// Set if the node is an element.
NODE_IS_ELEMENT = 0x00200000U,
+
+ // Set if the node has the accesskey attribute set.
+ NODE_HAS_ACCESSKEY = 0x00400000U,
+
+ // Set if the node has the accesskey attribute set.
+ NODE_HAS_NAME = 0x00800000U,
// Four bits for the script-type ID
- NODE_SCRIPT_TYPE_OFFSET = 22,
+ NODE_SCRIPT_TYPE_OFFSET = 24,
NODE_SCRIPT_TYPE_SIZE = 4,
// Remaining bits are node type specific.
NODE_TYPE_SPECIFIC_BITS_OFFSET =
NODE_SCRIPT_TYPE_OFFSET + NODE_SCRIPT_TYPE_SIZE
};
--- a/content/base/src/nsAttrValue.cpp
+++ b/content/base/src/nsAttrValue.cpp
@@ -1137,47 +1137,54 @@ nsAttrValue::SetColorValue(nscolor aColo
cont->mStringBits = reinterpret_cast<PtrBits>(buf) | eStringBase;
}
PRBool
nsAttrValue::ParseColor(const nsAString& aString, nsIDocument* aDocument)
{
ResetIfSet();
+ // FIXME (partially, at least): HTML5's algorithm says we shouldn't do
+ // the whitespace compression, trimming, or the test for emptiness.
+ // (I'm a little skeptical that we shouldn't do the whitespace
+ // trimming; WebKit also does it.)
nsAutoString colorStr(aString);
colorStr.CompressWhitespace(PR_TRUE, PR_TRUE);
if (colorStr.IsEmpty()) {
return PR_FALSE;
}
nscolor color;
// No color names begin with a '#'; in standards mode, all acceptable
// numeric colors do.
if (colorStr.First() == '#') {
- colorStr.Cut(0, 1);
- if (NS_HexToRGB(colorStr, &color)) {
+ nsDependentString withoutHash(colorStr.get() + 1, colorStr.Length() - 1);
+ if (NS_HexToRGB(withoutHash, &color)) {
SetColorValue(color, aString);
return PR_TRUE;
}
} else {
if (NS_ColorNameToRGB(colorStr, &color)) {
SetColorValue(color, aString);
return PR_TRUE;
}
}
- if (aDocument->GetCompatibilityMode() != eCompatibility_NavQuirks) {
- return PR_FALSE;
+ // FIXME (maybe): HTML5 says we should handle system colors. This
+ // means we probably need another storage type, since we'd need to
+ // handle dynamic changes. However, I think this is a bad idea:
+ // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-May/026449.html
+
+ // Use NS_LooseHexToRGB as a fallback if nothing above worked.
+ if (NS_LooseHexToRGB(colorStr, &color)) {
+ SetColorValue(color, aString);
+ return PR_TRUE;
}
- // In compatibility mode, try LooseHexToRGB as a fallback for either
- // of the above two possibilities.
- NS_LooseHexToRGB(colorStr, &color);
- SetColorValue(color, aString);
- return PR_TRUE;
+ return PR_FALSE;
}
PRBool nsAttrValue::ParseFloatValue(const nsAString& aString)
{
ResetIfSet();
PRInt32 ec;
float val = PromiseFlatString(aString).ToFloat(&ec);
--- a/content/base/src/nsAttrValue.h
+++ b/content/base/src/nsAttrValue.h
@@ -269,17 +269,18 @@ public:
* http://dev.w3.org/html5/spec/common-dom-interfaces.html#limited-to-only-non-negative-numbers-greater-than-zero
*
* @param aString the string to parse
* @return whether the value was valid
*/
PRBool ParsePositiveIntValue(const nsAString& aString);
/**
- * Parse a string into a color.
+ * Parse a string into a color. This implements what HTML5 calls the
+ * "rules for parsing a legacy color value".
*
* @param aString the string to parse
* @param aDocument the document (to find out whether we're in quirks mode)
* @return whether the value could be parsed
*/
PRBool ParseColor(const nsAString& aString, nsIDocument* aDocument);
/**
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -41,16 +41,17 @@
#include "nsIContentIterator.h"
#include "nsRange.h"
#include "nsIContent.h"
#include "nsIDOMText.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsContentUtils.h"
#include "nsINode.h"
+#include "nsCycleCollectionParticipant.h"
// couple of utility static functs
///////////////////////////////////////////////////////////////////////////
// ContentHasChildren: returns true if the node has children
//
static inline PRBool
NodeHasChildren(nsINode *aNode)
@@ -113,17 +114,18 @@ NodeIsInTraversalRange(nsINode *aNode, P
/*
* A simple iterator class for traversing the content in "close tag" order
*/
class nsContentIterator : public nsIContentIterator //, public nsIEnumerator
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsContentIterator)
nsContentIterator();
virtual ~nsContentIterator();
// nsIContentIterator interface methods ------------------------------
virtual nsresult Init(nsINode* aRoot);
@@ -247,18 +249,30 @@ nsresult NS_NewPreContentIterator(nsICon
return NS_OK;
}
/******************************************************
* XPCOM cruft
******************************************************/
-NS_IMPL_ISUPPORTS1(nsContentIterator, nsIContentIterator)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsContentIterator)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsContentIterator)
+NS_INTERFACE_MAP_BEGIN(nsContentIterator)
+ NS_INTERFACE_MAP_ENTRY(nsIContentIterator)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentIterator)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsContentIterator)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_4(nsContentIterator,
+ mCurNode,
+ mFirst,
+ mLast,
+ mCommonParent)
/******************************************************
* constructor/destructor
******************************************************/
nsContentIterator::nsContentIterator() :
// don't need to explicitly initialize |nsCOMPtr|s, they will automatically be NULL
mCachedIndex(0), mIsDone(PR_FALSE), mPre(PR_FALSE)
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -4891,45 +4891,16 @@ nsContentUtils::EqualsIgnoreASCIICase(co
/* static */
void
nsAutoGCRoot::Shutdown()
{
NS_IF_RELEASE(sJSRuntimeService);
}
-nsIAtom*
-nsContentUtils::IsNamedItem(Element* aElement)
-{
- // Only the content types reflected in Level 0 with a NAME
- // attribute are registered. Images, layers and forms always get
- // reflected up to the document. Applets and embeds only go
- // to the closest container (which could be a form).
- nsGenericHTMLElement* elm = nsGenericHTMLElement::FromContent(aElement);
- if (!elm) {
- return nsnull;
- }
-
- nsIAtom* tag = elm->Tag();
- if (tag != nsGkAtoms::img &&
- tag != nsGkAtoms::form &&
- tag != nsGkAtoms::applet &&
- tag != nsGkAtoms::embed &&
- tag != nsGkAtoms::object) {
- return nsnull;
- }
-
- const nsAttrValue* val = elm->GetParsedAttr(nsGkAtoms::name);
- if (val && val->Type() == nsAttrValue::eAtom) {
- return val->GetAtomValue();
- }
-
- return nsnull;
-}
-
/* static */
nsIInterfaceRequestor*
nsContentUtils::GetSameOriginChecker()
{
if (!sSameOriginChecker) {
sSameOriginChecker = new nsSameOriginChecker();
NS_IF_ADDREF(sSameOriginChecker);
}
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1449,17 +1449,17 @@ nsDocument::~nsDocument()
if (mSubDocuments) {
PL_DHashTableDestroy(mSubDocuments);
mSubDocuments = nsnull;
}
// Destroy link map now so we don't waste time removing
// links one by one
- DestroyLinkMap();
+ DestroyElementMaps();
nsAutoScriptBlocker scriptBlocker;
PRInt32 indx; // must be signed
PRUint32 count = mChildren.ChildCount();
for (indx = PRInt32(count) - 1; indx >= 0; --indx) {
mChildren.ChildAt(indx)->UnbindFromTree();
mChildren.RemoveChildAt(indx);
@@ -1878,34 +1878,32 @@ nsDocument::ResetToURI(nsIURI *aURI, nsI
#ifdef PR_LOGGING
if (gDocumentLeakPRLog && PR_LOG_TEST(gDocumentLeakPRLog, PR_LOG_DEBUG)) {
nsCAutoString spec;
aURI->GetSpec(spec);
PR_LogPrint("DOCUMENT %p ResetToURI %s", this, spec.get());
}
#endif
- mIdentifierMap.Clear();
-
SetPrincipal(nsnull);
mSecurityInfo = nsnull;
mDocumentLoadGroup = nsnull;
// Delete references to sub-documents and kill the subdocument map,
// if any. It holds strong references
if (mSubDocuments) {
PL_DHashTableDestroy(mSubDocuments);
mSubDocuments = nsnull;
}
// Destroy link map now so we don't waste time removing
// links one by one
- DestroyLinkMap();
+ DestroyElementMaps();
PRUint32 count = mChildren.ChildCount();
{ // Scope for update
MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, PR_TRUE);
for (PRInt32 i = PRInt32(count) - 1; i >= 0; i--) {
nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
if (nsINode::GetFirstChild() == content) {
@@ -2329,189 +2327,70 @@ nsDocument::GetLastModified(nsAString& a
// (or even the current time), fall back to what NS4.x returned.
aLastModified.Assign(NS_LITERAL_STRING("01/01/1970 00:00:00"));
}
return NS_OK;
}
void
-nsDocument::UpdateNameTableEntry(Element *aElement)
+nsDocument::AddToNameTable(Element *aElement, nsIAtom* aName)
{
if (!mIsRegularHTML)
return;
- nsIAtom* name = nsContentUtils::IsNamedItem(aElement);
- if (!name)
- return;
-
- nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(name);
- if (!entry) {
- // We're not tracking the elements with this name
- return;
- }
-
- entry->AddNameElement(aElement);
+ nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
+
+ // entry is null if we're not tracking the elements with this name
+
+ if (entry) {
+ entry->AddNameElement(aElement);
+ }
}
void
-nsDocument::RemoveFromNameTable(Element *aElement)
-{
- if (!mIsRegularHTML)
+nsDocument::RemoveFromNameTable(Element *aElement, nsIAtom* aName)
+{
+ // Speed up document teardown
+ if (!mIsRegularHTML || mIdentifierMap.Count() == 0)
return;
- nsIAtom* name = nsContentUtils::IsNamedItem(aElement);
- if (!name)
+ nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aName);
+ if (!entry) // Should never be false unless we had OOM when adding the entry
return;
- nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(name);
- if (!entry) {
- // We're not tracking the elements with this name
- return;
- }
-
entry->RemoveNameElement(aElement);
}
void
-nsDocument::UpdateIdTableEntry(Element *aElement)
-{
- nsIAtom* id = aElement->GetID();
- if (!id)
- return;
-
- nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(id);
+nsDocument::AddToIdTable(Element *aElement, nsIAtom* aId)
+{
+ nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aId);
if (entry) { /* True except on OOM */
entry->AddIdElement(aElement);
}
}
void
-nsDocument::RemoveFromIdTable(Element *aElement)
-{
- nsIAtom* id = aElement->GetID();
- if (!id)
+nsDocument::RemoveFromIdTable(Element *aElement, nsIAtom* aId)
+{
+ NS_ASSERTION(aId, "huhwhatnow?");
+
+ // Speed up document teardown
+ if (mIdentifierMap.Count() == 0) {
return;
-
- nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(id);
- if (!entry) /* Should be false unless we had OOM when adding the entry */
+ }
+
+ nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aId);
+ if (!entry) // Can be null for XML elements with changing ids.
return;
if (entry->RemoveIdElement(aElement)) {
- mIdentifierMap.RemoveEntry(id);
- }
-}
-
-void
-nsDocument::UnregisterNamedItems(nsIContent *aContent)
-{
- if (!aContent->IsElement()) {
- // non-element nodes are not named items nor can they have children.
- return;
- }
-
- RemoveFromNameTable(aContent->AsElement());
- RemoveFromIdTable(aContent->AsElement());
-
- for (nsINode::ChildIterator iter(aContent); !iter.IsDone(); iter.Next()) {
- UnregisterNamedItems(iter);
- }
-}
-
-void
-nsDocument::RegisterNamedItems(nsIContent *aContent)
-{
- if (!aContent->IsElement()) {
- // non-element nodes are not named items nor can they have children.
- return;
- }
-
- UpdateNameTableEntry(aContent->AsElement());
- UpdateIdTableEntry(aContent->AsElement());
-
- for (nsINode::ChildIterator iter(aContent); !iter.IsDone(); iter.Next()) {
- RegisterNamedItems(iter);
- }
-}
-
-void
-nsDocument::ContentAppended(nsIDocument* aDocument,
- nsIContent* aContainer,
- nsIContent* aFirstNewContent,
- PRInt32 aNewIndexInContainer)
-{
- NS_ASSERTION(aDocument == this, "unexpected doc");
-
- for (nsINode::ChildIterator iter(aContainer, aNewIndexInContainer);
- !iter.IsDone();
- iter.Next()) {
- RegisterNamedItems(iter);
- }
-}
-
-void
-nsDocument::ContentInserted(nsIDocument* aDocument,
- nsIContent* aContainer,
- nsIContent* aContent,
- PRInt32 aIndexInContainer)
-{
- NS_ASSERTION(aDocument == this, "unexpected doc");
-
- NS_ABORT_IF_FALSE(aContent, "Null content!");
-
- RegisterNamedItems(aContent);
-}
-
-void
-nsDocument::ContentRemoved(nsIDocument* aDocument,
- nsIContent* aContainer,
- nsIContent* aChild,
- PRInt32 aIndexInContainer)
-{
- NS_ASSERTION(aDocument == this, "unexpected doc");
-
- NS_ABORT_IF_FALSE(aChild, "Null content!");
-
- UnregisterNamedItems(aChild);
-}
-
-void
-nsDocument::AttributeWillChange(nsIDocument* aDocument,
- nsIContent* aContent, PRInt32 aNameSpaceID,
- nsIAtom* aAttribute, PRInt32 aModType)
-{
- NS_ABORT_IF_FALSE(aContent && aContent->IsElement(), "Null content!");
- NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!");
-
- if (aNameSpaceID != kNameSpaceID_None)
- return;
- if (aAttribute == nsGkAtoms::name) {
- RemoveFromNameTable(aContent->AsElement());
- } else if (aAttribute == aContent->GetIDAttributeName()) {
- RemoveFromIdTable(aContent->AsElement());
- }
-}
-
-void
-nsDocument::AttributeChanged(nsIDocument* aDocument,
- nsIContent* aContent, PRInt32 aNameSpaceID,
- nsIAtom* aAttribute, PRInt32 aModType)
-{
- NS_ASSERTION(aDocument == this, "unexpected doc");
-
- NS_ABORT_IF_FALSE(aContent && aContent->IsElement(), "Null content!");
- NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!");
-
- if (aNameSpaceID != kNameSpaceID_None)
- return;
- if (aAttribute == nsGkAtoms::name) {
- UpdateNameTableEntry(aContent->AsElement());
- } else if (aAttribute == aContent->GetIDAttributeName()) {
- UpdateIdTableEntry(aContent->AsElement());
+ mIdentifierMap.RemoveEntry(aId);
}
}
nsIPrincipal*
nsDocument::GetPrincipal()
{
return NodePrincipal();
}
@@ -3320,17 +3199,17 @@ nsDocument::RemoveChildAt(PRUint32 aInde
NS_ASSERTION(aMutationEvent, "Someone tried to inhibit mutations on document child removal.");
nsCOMPtr<nsIContent> oldKid = GetChildAt(aIndex);
if (!oldKid) {
return NS_OK;
}
if (oldKid->IsElement()) {
// Destroy the link map up front before we mess with the child list.
- DestroyLinkMap();
+ DestroyElementMaps();
}
nsresult rv =
doRemoveChildAt(aIndex, aNotify, oldKid, mChildren, aMutationEvent);
mCachedRootElement = nsnull;
return rv;
}
@@ -3854,118 +3733,70 @@ nsDocument::CheckGetElementByIdArg(const
EmptyString(), 0, 0,
nsIScriptError::warningFlag,
"DOM");
return PR_FALSE;
}
return PR_TRUE;
}
-nsIdentifierMapEntry*
-nsDocument::GetElementByIdInternal(nsIAtom* aID)
-{
- // We don't have to flush before we do the initial hashtable lookup, since if
- // the id is already in the hashtable it couldn't have been removed without
- // us being notified (all removals notify immediately, as far as I can tell).
- // So do the lookup first.
- nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aID);
- NS_ENSURE_TRUE(entry, nsnull);
-
- if (entry->GetIdElement())
- return entry;
-
- // Now we have to flush. It could be that we know nothing about this ID yet
- // but more content has been added to the document since. Note that we have
- // to flush notifications, so that the entry will get updated properly.
-
- // Make sure to stash away the current generation so we can check whether
- // the table changes when we flush.
- PRUint32 generation = mIdentifierMap.GetGeneration();
-
- FlushPendingNotifications(Flush_ContentAndNotify);
-
- if (generation != mIdentifierMap.GetGeneration()) {
- // Table changed, so the entry pointer is no longer valid; look up the
- // entry again, adding if necessary (the adding may be necessary in case
- // the flush actually deleted entries).
- entry = mIdentifierMap.PutEntry(aID);
- }
-
- return entry;
-}
-
Element*
-nsDocument::GetElementById(const nsAString& aElementId, nsresult *aResult)
+nsDocument::GetElementById(const nsAString& aElementId)
{
nsCOMPtr<nsIAtom> idAtom(do_GetAtom(aElementId));
if (!idAtom) {
- *aResult = NS_ERROR_OUT_OF_MEMORY;
-
+ // This can only fail due to OOM when the atom doesn't exist, in which
+ // case there can't be an entry for it.
return nsnull;
}
if (!CheckGetElementByIdArg(idAtom)) {
- *aResult = NS_OK;
-
return nsnull;
}
- nsIdentifierMapEntry *entry = GetElementByIdInternal(idAtom);
- if (!entry) {
- *aResult = NS_ERROR_OUT_OF_MEMORY;
-
- return nsnull;
- }
-
- *aResult = NS_OK;
-
- return entry->GetIdElement();
+ nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(idAtom);
+ return entry ? entry->GetIdElement() : nsnull;
}
NS_IMETHODIMP
nsDocument::GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
{
- nsresult rv;
- Element *content = GetElementById(aId, &rv);
+ Element *content = GetElementById(aId);
if (content) {
- rv = CallQueryInterface(content, aReturn);
- }
- else {
- *aReturn = nsnull;
- }
-
- return rv;
+ return CallQueryInterface(content, aReturn);
+ }
+
+ *aReturn = nsnull;
+
+ return NS_OK;
}
Element*
nsDocument::AddIDTargetObserver(nsIAtom* aID, IDTargetObserver aObserver,
void* aData)
{
if (!CheckGetElementByIdArg(aID))
return nsnull;
- nsIdentifierMapEntry *entry = GetElementByIdInternal(aID);
+ nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(aID);
NS_ENSURE_TRUE(entry, nsnull);
entry->AddContentChangeCallback(aObserver, aData);
return entry->GetIdElement();
}
void
nsDocument::RemoveIDTargetObserver(nsIAtom* aID,
IDTargetObserver aObserver, void* aData)
{
if (!CheckGetElementByIdArg(aID))
return;
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(aID);
if (!entry) {
- // We don't need to do the stuff that GetElementByIdInternal does;
- // if there's no entry already in mIdentifierMap, then there's no
- // callback to remove.
return;
}
entry->RemoveContentChangeCallback(aObserver, aData);
}
void
nsDocument::DispatchContentLoadedEvents()
@@ -7375,22 +7206,23 @@ nsDocument::ForgetLink(Link* aLink)
nsPtrHashKey<Link>* entry = mStyledLinks.GetEntry(aLink);
NS_ASSERTION(entry || mStyledLinksCleared,
"Document knows nothing about this Link!");
#endif
(void)mStyledLinks.RemoveEntry(aLink);
}
void
-nsDocument::DestroyLinkMap()
+nsDocument::DestroyElementMaps()
{
#ifdef DEBUG
mStyledLinksCleared = true;
#endif
mStyledLinks.Clear();
+ mIdentifierMap.Clear();
}
static
PLDHashOperator
EnumerateStyledLinks(nsPtrHashKey<Link>* aEntry, void* aArray)
{
nsTArray<Link*>* array = static_cast<nsTArray<Link*>*>(aArray);
(void)array->AppendElement(aEntry->GetKey());
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -646,16 +646,27 @@ public:
virtual nsIScriptGlobalObject* GetScopeObject();
/**
* Get the script loader for this document
*/
virtual nsScriptLoader* ScriptLoader();
/**
+ * Add/Remove an element to the document's id and name hashes
+ */
+ virtual void AddToIdTable(mozilla::dom::Element* aElement, nsIAtom* aId);
+ virtual void RemoveFromIdTable(mozilla::dom::Element* aElement,
+ nsIAtom* aId);
+ virtual void AddToNameTable(mozilla::dom::Element* aElement,
+ nsIAtom* aName);
+ virtual void RemoveFromNameTable(mozilla::dom::Element* aElement,
+ nsIAtom* aName);
+
+ /**
* Add a new observer of document change notifications. Whenever
* content is changed, appended, inserted or removed the observers are
* informed.
*/
virtual void AddObserver(nsIDocumentObserver* aObserver);
/**
* Remove an observer of document change notifications. This will
@@ -802,23 +813,16 @@ public:
NS_DECL_NSIDOMEVENTTARGET
// nsIDOM3EventTarget
NS_DECL_NSIDOM3EVENTTARGET
// nsIDOMNSEventTarget
NS_DECL_NSIDOMNSEVENTTARGET
- // nsIMutationObserver
- NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
- NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
- NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
- NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
- NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
-
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();
// nsIApplicationCacheContainer
NS_DECL_NSIAPPLICATIONCACHECONTAINER
virtual nsresult Init();
@@ -932,27 +936,20 @@ public:
virtual void SetChangeScrollPosWhenScrollingToRef(PRBool aValue);
already_AddRefed<nsContentList>
GetElementsByTagName(const nsAString& aTagName);
already_AddRefed<nsContentList>
GetElementsByTagNameNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName);
- virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId,
- nsresult *aResult);
+ virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId);
protected:
friend class nsNodeUtils;
- void RegisterNamedItems(nsIContent *aContent);
- void UnregisterNamedItems(nsIContent *aContent);
- void UpdateNameTableEntry(Element *aElement);
- void UpdateIdTableEntry(Element *aElement);
- void RemoveFromNameTable(Element *aElement);
- void RemoveFromIdTable(Element *aElement);
/**
* Check that aId is not empty and log a message to the console
* service if it is.
* @returns PR_TRUE if aId looks correct, PR_FALSE otherwise.
*/
static PRBool CheckGetElementByIdArg(const nsIAtom* aId);
nsIdentifierMapEntry* GetElementByIdInternal(nsIAtom* aID);
@@ -961,18 +958,18 @@ protected:
void RetrieveRelevantHeaders(nsIChannel *aChannel);
static PRBool TryChannelCharset(nsIChannel *aChannel,
PRInt32& aCharsetSource,
nsACString& aCharset);
// Call this before the document does something that will unbind all content.
- // That will stop us from resolving URIs for all links as they are removed.
- void DestroyLinkMap();
+ // That will stop us from doing a lot of work as each element is removed.
+ void DestroyElementMaps();
// Refreshes the hrefs of all the links in the document.
void RefreshLinkHrefs();
nsIContent* GetFirstBaseNodeWithHref();
nsresult SetFirstBaseNodeWithHref(nsIContent *node);
// Get the first <title> element with the given IsNodeOfType type, or
--- a/content/base/src/nsDocumentFragment.cpp
+++ b/content/base/src/nsDocumentFragment.cpp
@@ -149,16 +149,19 @@ public:
}
virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const
{
return nsnull;
}
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
+ virtual nsIAtom* DoGetID() const;
+ virtual nsIAtom *GetIDAttributeName() const;
+
protected:
nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
};
nsresult
NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
nsNodeInfoManager *aNodeInfoManager)
{
@@ -190,16 +193,28 @@ nsDocumentFragment::~nsDocumentFragment(
}
PRBool
nsDocumentFragment::IsNodeOfType(PRUint32 aFlags) const
{
return !(aFlags & ~(eCONTENT | eDOCUMENT_FRAGMENT));
}
+nsIAtom*
+nsDocumentFragment::DoGetID() const
+{
+ return nsnull;
+}
+
+nsIAtom*
+nsDocumentFragment::GetIDAttributeName() const
+{
+ return nsnull;
+}
+
DOMCI_DATA(DocumentFragment, nsDocumentFragment)
// QueryInterface implementation for nsDocumentFragment
NS_INTERFACE_TABLE_HEAD(nsDocumentFragment)
NS_NODE_INTERFACE_TABLE2(nsDocumentFragment, nsIDOMNode,
nsIDOMDocumentFragment)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DocumentFragment)
NS_INTERFACE_MAP_END_INHERITING(nsGenericElement)
--- a/content/base/src/nsGenericDOMDataNode.cpp
+++ b/content/base/src/nsGenericDOMDataNode.cpp
@@ -560,17 +560,17 @@ nsGenericDOMDataNode::UnbindFromTree(PRB
UnsetFlags(NS_CREATE_FRAME_IF_NON_WHITESPACE |
NS_REFRAME_IF_WHITESPACE);
nsIDocument *document = GetCurrentDoc();
if (document) {
// Notify XBL- & nsIAnonymousContentCreator-generated
// anonymous content that the document is changing.
// This is needed to update the insertion point.
- document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
+ document->BindingManager()->RemovedFromDocument(this, document);
}
mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT;
nsDataSlots *slots = GetExistingDataSlots();
if (slots) {
slots->mBindingParent = nsnull;
}
@@ -1103,17 +1103,17 @@ already_AddRefed<nsIAtom>
nsGenericDOMDataNode::GetCurrentValueAtom()
{
nsAutoString val;
GetData(val);
return NS_NewAtom(val);
}
nsIAtom*
-nsGenericDOMDataNode::GetID() const
+nsGenericDOMDataNode::DoGetID() const
{
return nsnull;
}
const nsAttrValue*
nsGenericDOMDataNode::DoGetClasses() const
{
NS_NOTREACHED("Shouldn't ever be called");
--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -243,17 +243,17 @@ public:
#endif
virtual nsIContent *GetBindingParent() const;
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
virtual already_AddRefed<nsIURI> GetBaseURI() const;
virtual PRBool IsLink(nsIURI** aURI) const;
- virtual nsIAtom* GetID() const;
+ virtual nsIAtom* DoGetID() const;
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual nsICSSStyleRule* GetInlineStyleRule();
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const;
virtual nsIAtom *GetClassAttributeName() const;
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -2964,17 +2964,17 @@ nsGenericElement::UnbindFromTree(PRBool
nsIDocument *document =
HasFlag(NODE_FORCE_XBL_BINDINGS) ? GetOwnerDoc() : GetCurrentDoc();
mParentPtrBits = aNullParent ? 0 : mParentPtrBits & ~PARENT_BIT_INDOCUMENT;
if (document) {
// Notify XBL- & nsIAnonymousContentCreator-generated
// anonymous content that the document is changing.
- document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
+ document->BindingManager()->RemovedFromDocument(this, document);
document->ClearBoxObjectFor(this);
}
// Ensure that CSS transitions don't continue on an element at a
// different place in the tree (even if reinserted before next
// animation refresh).
// FIXME (Bug 522599): Need a test for this.
@@ -3244,48 +3244,16 @@ nsGenericElement::DispatchDOMEvent(nsEve
nsPresContext* aPresContext,
nsEventStatus* aEventStatus)
{
return nsEventDispatcher::DispatchDOMEvent(static_cast<nsIContent*>(this),
aEvent, aDOMEvent,
aPresContext, aEventStatus);
}
-nsIAtom*
-nsGenericElement::GetID() const
-{
- if (!HasFlag(NODE_MAY_HAVE_ID)) {
- return nsnull;
- }
-
- nsIAtom* IDName = GetIDAttributeName();
- if (IDName) {
- const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(IDName);
- if (attrVal){
- if (attrVal->Type() == nsAttrValue::eAtom) {
- return attrVal->GetAtomValue();
- }
- if(attrVal->IsEmptyString()){
- return nsnull;
- }
- // Check if the ID has been stored as a string.
- // This would occur if the ID attribute name changed after
- // the ID was parsed.
- if (attrVal->Type() == nsAttrValue::eString) {
- nsAutoString idVal(attrVal->GetStringValue());
-
- // Create an atom from the value and set it into the attribute list.
- const_cast<nsAttrValue*>(attrVal)->ParseAtom(idVal);
- return attrVal->GetAtomValue();
- }
- }
- }
- return nsnull;
-}
-
const nsAttrValue*
nsGenericElement::DoGetClasses() const
{
NS_NOTREACHED("Shouldn't ever be called");
return nsnull;
}
NS_IMETHODIMP
@@ -3367,22 +3335,16 @@ nsGenericElement::IsAttributeMapped(cons
nsChangeHint
nsGenericElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const
{
return nsChangeHint(0);
}
nsIAtom *
-nsGenericElement::GetIDAttributeName() const
-{
- return mNodeInfo->GetIDAttributeAtom();
-}
-
-nsIAtom *
nsGenericElement::GetClassAttributeName() const
{
return nsnull;
}
PRBool
nsGenericElement::FindAttributeDependence(const nsIAtom* aAttribute,
const MappedAttributeEntry* const aMaps[],
@@ -3799,17 +3761,17 @@ nsGenericElement::GetPrimaryFrame(mozFlu
return GetPrimaryFrame();
}
void
nsGenericElement::DestroyContent()
{
nsIDocument *document = GetOwnerDoc();
if (document) {
- document->BindingManager()->ChangeDocumentFor(this, document, nsnull);
+ document->BindingManager()->RemovedFromDocument(this, document);
document->ClearBoxObjectFor(this);
}
// XXX We really should let cycle collection do this, but that currently still
// leaks (see https://bugzilla.mozilla.org/show_bug.cgi?id=406684).
nsContentUtils::ReleaseWrapper(this, this);
PRUint32 i, count = mAttrsAndChildren.ChildCount();
@@ -4360,19 +4322,18 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
if (tmp->IsXUL())
NS_IF_RELEASE(slots->mControllers);
slots->mChildrenList = nsnull;
}
}
{
nsIDocument *doc;
- if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc()) &&
- tmp->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
- doc->BindingManager()->ChangeDocumentFor(tmp, doc, nsnull);
+ if (!tmp->GetNodeParent() && (doc = tmp->GetOwnerDoc())) {
+ doc->BindingManager()->RemovedFromDocument(tmp, doc);
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END
@@ -4728,25 +4689,16 @@ nsGenericElement::SetAttrAndNotify(PRInt
}
PRBool
nsGenericElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
- if (aNamespaceID == kNameSpaceID_None &&
- aAttribute == GetIDAttributeName() && !aValue.IsEmpty()) {
- SetFlags(NODE_MAY_HAVE_ID);
- // Store id as an atom. id="" means that the element has no id,
- // not that it has an emptystring as the id.
- aResult.ParseAtom(aValue);
- return PR_TRUE;
- }
-
return PR_FALSE;
}
PRBool
nsGenericElement::SetMappedAttribute(nsIDocument* aDocument,
nsIAtom* aName,
nsAttrValue& aValue,
nsresult* aRetval)
--- a/content/base/src/nsGenericElement.h
+++ b/content/base/src/nsGenericElement.h
@@ -374,17 +374,16 @@ public:
// nsIContent interface methods
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
PRBool aNullParent = PR_TRUE);
virtual already_AddRefed<nsINodeList> GetChildren(PRInt32 aChildType);
- virtual nsIAtom *GetIDAttributeName() const;
virtual nsIAtom *GetClassAttributeName() const;
virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue, PRBool aNotify)
{
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
}
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
@@ -446,17 +445,16 @@ public:
{
List(out, aIndent, EmptyCString());
}
virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
void List(FILE* out, PRInt32 aIndent, const nsCString& aPrefix) const;
void ListAttributes(FILE* out) const;
#endif
- virtual nsIAtom* GetID() const;
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual nsICSSStyleRule* GetInlineStyleRule();
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
NS_IMETHOD_(PRBool)
IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const;
@@ -989,25 +987,39 @@ protected:
void UnregisterFreezableElement() {
nsIDocument* doc = GetOwnerDoc();
if (doc) {
doc->UnregisterFreezableElement(this);
}
}
/**
- * GetContentsAsText will take all the textnodes that are children
- * of |this| and concatenate the text in them into aText. It
- * completely ignores any non-text-node children of |this|; in
- * particular it does not descend into any children of |this| that
- * happen to be container elements.
- *
- * @param aText the resulting text [OUT]
+ * Add/remove this element to the documents id cache
*/
- void GetContentsAsText(nsAString& aText);
+ void AddToIdTable(nsIAtom* aId) {
+ NS_ASSERTION(HasFlag(NODE_HAS_ID), "Node lacking NODE_HAS_ID flag");
+ nsIDocument* doc = GetCurrentDoc();
+ if (doc && (!IsInAnonymousSubtree() || doc->IsXUL())) {
+ doc->AddToIdTable(this, aId);
+ }
+ }
+ void RemoveFromIdTable() {
+ if (HasFlag(NODE_HAS_ID)) {
+ nsIDocument* doc = GetCurrentDoc();
+ if (doc) {
+ nsIAtom* id = DoGetID();
+ // id can be null during mutation events evilness. Also, XUL elements
+ // loose their proto attributes during cc-unlink, so this can happen
+ // during cc-unlink too.
+ if (id) {
+ doc->RemoveFromIdTable(this, DoGetID());
+ }
+ }
+ }
+ }
/**
* Functions to carry out event default actions for links of all types
* (HTML links, XLinks, SVG "XLinks", etc.)
*/
/**
* Check that we meet the conditions to handle a link event
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -573,23 +573,16 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
// aNode's children.
PRUint32 i, length = aNode->GetChildCount();
for (i = 0; i < length; ++i) {
nsCOMPtr<nsINode> child;
rv = CloneAndAdopt(aNode->GetChildAt(i), aClone, PR_TRUE, nodeInfoManager,
aCx, aOldScope, aNewScope, aNodesWithProperties,
clone, getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
- if (isDeepDocumentClone) {
- NS_ASSERTION(child->IsNodeOfType(nsINode::eCONTENT),
- "A clone of a child of a node is not nsIContent?");
-
- nsIContent* content = static_cast<nsIContent*>(child.get());
- static_cast<nsDocument*>(clone.get())->RegisterNamedItems(content);
- }
}
}
// XXX setting document on some nodes not in a document so XBL will bind
// and chrome won't break. Make XBL bind to document-less nodes!
// XXXbz Once this is fixed, fix up the asserts in all implementations of
// BindToTree to assert what they would like to assert, and fix the
// ChangeDocumentFor() call in nsXULElement::BindToTree as well. Also,
--- a/content/base/src/nsStyledElement.cpp
+++ b/content/base/src/nsStyledElement.cpp
@@ -66,16 +66,30 @@ nsStyledElement::GetClassAttributeName()
}
nsIAtom*
nsStyledElement::GetIDAttributeName() const
{
return nsGkAtoms::id;
}
+nsIAtom*
+nsStyledElement::DoGetID() const
+{
+ NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
+
+ // The nullcheck here is needed because nsGenericElement::UnsetAttr calls
+ // out to various code between removing the attribute and we get a chance to
+ // clear the NODE_HAS_ID flag.
+
+ const nsAttrValue* attr = mAttrsAndChildren.GetAttr(nsGkAtoms::id);
+
+ return attr ? attr->GetAtomValue() : nsnull;
+}
+
const nsAttrValue*
nsStyledElement::DoGetClasses() const
{
NS_ASSERTION(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call");
return mAttrsAndChildren.GetAttr(nsGkAtoms::_class);
}
PRBool
@@ -88,22 +102,55 @@ nsStyledElement::ParseAttribute(PRInt32
ParseStyleAttribute(aValue, aResult, PR_FALSE);
return PR_TRUE;
}
if (aAttribute == nsGkAtoms::_class) {
SetFlags(NODE_MAY_HAVE_CLASS);
aResult.ParseAtomArray(aValue);
return PR_TRUE;
}
+ if (aAttribute == nsGkAtoms::id) {
+ // Store id as an atom. id="" means that the element has no id,
+ // not that it has an emptystring as the id.
+ RemoveFromIdTable();
+ if (aValue.IsEmpty()) {
+ UnsetFlags(NODE_HAS_ID);
+ return PR_FALSE;
+ }
+ aResult.ParseAtom(aValue);
+ SetFlags(NODE_HAS_ID);
+ AddToIdTable(aResult.GetAtomValue());
+ return PR_TRUE;
+ }
}
return nsStyledElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
aResult);
}
+nsresult
+nsStyledElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+ PRBool aNotify)
+{
+ PRBool isId = PR_FALSE;
+ if (aAttribute == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) {
+ // Have to do this before clearing flag. See RemoveFromIdTable
+ RemoveFromIdTable();
+ isId = PR_TRUE;
+ }
+
+ nsresult rv = nsGenericElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
+
+ if (isId) {
+ UnsetFlags(NODE_HAS_ID);
+ }
+
+ return rv;
+}
+
NS_IMETHODIMP
nsStyledElement::SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify)
{
SetFlags(NODE_MAY_HAVE_STYLE);
PRBool modification = PR_FALSE;
nsAutoString oldValueStr;
PRBool hasListeners = aNotify &&
@@ -158,23 +205,38 @@ nsStyledElement::BindToTree(nsIDocument*
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
nsresult rv = nsStyledElementBase::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
- // XXXbz if we already have a style attr parsed, this won't do
- // anything... need to fix that.
- ReparseStyleAttribute(PR_FALSE);
+ if (aDocument && HasFlag(NODE_HAS_ID) && !GetBindingParent()) {
+ aDocument->AddToIdTable(this, DoGetID());
+ }
+
+ if (!IsXUL()) {
+ // XXXbz if we already have a style attr parsed, this won't do
+ // anything... need to fix that.
+ ReparseStyleAttribute(PR_FALSE);
+ }
- return rv;
+ return NS_OK;
}
+void
+nsStyledElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
+{
+ RemoveFromIdTable();
+
+ nsStyledElementBase::UnbindFromTree(aDeep, aNullParent);
+}
+
+
// ---------------------------------------------------------------
// Others and helpers
nsresult
nsStyledElement::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
{
nsGenericElement::nsDOMSlots *slots = GetDOMSlots();
NS_ENSURE_TRUE(slots, NS_ERROR_OUT_OF_MEMORY);
--- a/content/base/src/nsStyledElement.h
+++ b/content/base/src/nsStyledElement.h
@@ -59,27 +59,32 @@ class nsStyledElement : public nsStyledE
protected:
inline nsStyledElement(nsINodeInfo *aNodeInfo)
: nsStyledElementBase(aNodeInfo)
{}
public:
- // nsIContent interface methods for styling
+ // nsIContent interface methods
virtual nsIAtom* GetClassAttributeName() const;
virtual nsIAtom* GetIDAttributeName() const;
+ virtual nsIAtom* DoGetID() const;
virtual const nsAttrValue* DoGetClasses() const;
virtual nsICSSStyleRule* GetInlineStyleRule();
NS_IMETHOD SetInlineStyleRule(nsICSSStyleRule* aStyleRule, PRBool aNotify);
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers);
+ virtual void UnbindFromTree(PRBool aDeep, PRBool aNullParent);
+
+ virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+ PRBool aNotify);
protected:
/**
* Parse a style attr value into a CSS rulestruct (or, if there is no
* document, leave it as a string) and return as nsAttrValue.
*
* @param aValue the value to parse
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -338,16 +338,17 @@ include $(topsrcdir)/config/rules.mk
test_bug543870.html \
file_bug543870_img.jpg \
file_bug543870_inner.html \
file_bug543870_doc.html \
file_bug543870_text.txt \
test_bug475156.html \
bug475156.sjs \
test_bug544642.html \
+ test_bug564863.xhtml \
test_copypaste.html \
test_bug503481.html \
file_bug503481.sjs \
test_bug503481b.html \
file_bug503481b_inner.html \
test_viewport_scroll.html \
test_CSP.html \
file_CSP.sjs \
@@ -385,16 +386,18 @@ include $(topsrcdir)/config/rules.mk
file_csp_redirects_resource.sjs \
test_bug346485.html \
test_bug560780.html \
test_bug562652.html \
test_bug562137.html \
file_bug562137.txt \
test_bug548193.html \
file_bug548193.sjs \
+ test_html_colors_quirks.html \
+ test_html_colors_standards.html \
$(NULL)
# This test fails on the Mac for some reason
ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
_TEST_FILES2 += test_copyimage.html \
$(NULL)
endif
--- a/content/base/test/test_bug493881.html
+++ b/content/base/test/test_bug493881.html
@@ -10,17 +10,17 @@ https://bugzilla.mozilla.org/show_bug.cg
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="test_bug493881.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<style type="text/css">
</style>
</head>
-<body>
+<body id="body">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=493881"
target="_blank" >Mozilla Bug 493881</a>
<p id="display"></p>
<a id="nonvisitedlink" href="http://www.example.com/">Non-visited link</a>
<a id="visitedlink" href="">Visited link</a>
--- a/content/base/test/test_bug493881.js
+++ b/content/base/test/test_bug493881.js
@@ -5,17 +5,17 @@
*/
SimpleTest.waitForExplicitFinish();
var legacyProps = ["fgColor", "bgColor", "linkColor", "vlinkColor", "alinkColor"];
var testColors = ["blue", "silver", "green", "orange", "red"];
var rgbTestColors = ["rgb(255, 0, 0)", "rgb(192, 192, 192)", "rgb(0, 128, 0)", "rgb(255, 165, 0)", "rgb(255, 0, 0)"];
var idPropList = [ {id: "plaintext", prop: "color"},
- {id: "plaintext", prop: "background-color"},
+ {id: "body", prop: "background-color"},
{id: "nonvisitedlink", prop: "color"},
{id: "visitedlink", prop: "color"} ];
var initialValues = [];
function setAndTestProperty(prop, color) {
var initial = document[prop];
document[prop] = color;
is(document[prop], initial, "document[" + prop + "] not ignored before body");
@@ -53,20 +53,20 @@ addLoadEvent( function() {
// Verify that setting legacy color props to undefined after BODY loads will cause them
// to be read as the string "undefined".
for (var i = 0; i < legacyProps.length; i++) {
document[legacyProps[i]] = undefined;
is(document[legacyProps[i]], "undefined",
"Unexpected value of " + legacyProps[i] + " after setting to undefined");
}
- // Verify that setting legacy color props to undefined did not affect rendering
- // (computed styles).
+ // Verify that setting legacy color props to undefined led to result
+ // of parsing undefined as a color.
for (i = 0; i < idPropList.length; i++) {
var style = window.getComputedStyle(document.getElementById(idPropList[i].id), null);
var color = style.getPropertyValue(idPropList[i].prop);
- is(color, idPropList[i].initialComputedColor,
- "element's style changed by setting legacy prop to undefined");
+ is(color, "rgb(0, 239, 14)",
+ "element's style should get result of parsing undefined as a color");
}
// Mark the test as finished.
setTimeout(SimpleTest.finish, 0);
});
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug564863.xhtml
@@ -0,0 +1,328 @@
+<!DOCTYPE html [
+<!ATTLIST ns:x id ID #REQUIRED>
+<!ATTLIST ns2:x id_2 ID #REQUIRED>
+]>
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:ns="urn:namespace"
+ xmlns:ns2="urn:namespace">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=564863
+-->
+<head>
+ <title>Test for Bug 564863</title>
+ <script type="text/javascript" src="/MochiKit/packed.js"></script>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+<style>
+#div_id {
+ color: rgb(10, 10, 10);
+}
+#a_id {
+ color: rgb(20, 20, 20);
+}
+#xul_id {
+ color: rgb(30, 30, 30);
+}
+#svg_id {
+ color: rgb(40, 40, 40);
+}
+#ns_id {
+ color: rgb(50, 50, 50);
+}
+#ns2_id {
+ color: rgb(60, 60, 60);
+}
+</style>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=564863">Mozilla Bug 564863</a>
+<!-- Elements to ensure we have nodeinfos with id-attribute set -->
+<div><ns:x id="ns-holder"/><ns2:x id_2="ns2-holder"/></div>
+
+<!-- DOM to muck around with for tests -->
+<p id="root">
+<div id="div_id" />
+<a id="a_id" />
+<xul:button id="xul_id" />
+<svg:svg><svg:g id="svg_id" /></svg:svg>
+<ns:x id="ns_id" />
+</p>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+
+root = $('root');
+div = root.children[0];
+a = root.children[1];
+xul = root.children[2];
+svg = root.children[3].firstChild;
+nsx = root.children[4];
+
+var div_cs = getComputedStyle(div, "");
+var a_cs = getComputedStyle(a, "");
+var xul_cs = getComputedStyle(xul, "");
+var svg_cs = getComputedStyle(svg, "");
+var nsx_cs = getComputedStyle(nsx, "");
+
+function checkHasId(test) {
+ // Check computed style first to avoid flushes from hiding problems
+ checkHasIdNoGEBI(test);
+
+ is($("div_id"), div, "div getElementById " + test);
+ is($("a_id"), a, "a getElementById " + test);
+ is($("xul_id"), xul, "xul getElementById " + test);
+ is($("svg_id"), svg, "svg getElementById " + test);
+ is($("ns_id"), nsx, "ns getElementById " + test);
+}
+
+function checkHasIdNoGEBI(test) {
+ is(div_cs.color, "rgb(10, 10, 10)", "div color " + test);
+ is(a_cs.color, "rgb(20, 20, 20)", "a color " + test);
+ is(xul_cs.color, "rgb(30, 30, 30)", "xul color " + test);
+ is(svg_cs.color, "rgb(40, 40, 40)", "svg color " + test);
+ is(nsx_cs.color, "rgb(50, 50, 50)", "nsx color " + test);
+
+ is(div.id, "div_id", "div id " + test);
+ is(a.id, "a_id", "a id " + test);
+ is(xul.id, "xul_id", "xul id " + test);
+ is(svg.id, "svg_id", "svg id " + test);
+ is (nsx.getAttribute("id"), "ns_id", "ns id " + test);
+}
+
+function checkHasNoId(removed, test) {
+ is(div_cs.color, "rgb(0, 0, 0)", "div color " + test);
+ is(a_cs.color, "rgb(0, 0, 0)", "a color " + test);
+ is(xul_cs.color, "rgb(0, 0, 0)", "xul color " + test);
+ is(svg_cs.color, "rgb(0, 0, 0)", "svg color " + test);
+ is(nsx_cs.color, "rgb(0, 0, 0)", "nsx color " + test);
+
+ attrValue = removed ? null : "";
+
+ is(div.id, "", "div id " + test);
+ is(a.id, "", "a id " + test);
+ is(xul.id, "", "xul id " + test);
+ is(svg.id, "", "svg id " + test);
+
+ is(div.getAttribute("id"), attrValue, "div getAttribute " + test);
+ is(a.getAttribute("id"), attrValue, "a getAttribute " + test);
+ is(xul.getAttribute("id"), "", "xul getAttribute " + test);
+ is(svg.getAttribute("id"), attrValue, "svg getAttribute " + test);
+ is(nsx.getAttribute("id"), attrValue, "ns getAttribute " + test);
+
+ is($("div_id"), null, "div getElementById " + test);
+ is($("a_id"), null, "a getElementById " + test);
+ is($("xul_id"), null, "xul getElementById " + test);
+ is($("svg_id"), null, "svg getElementById " + test);
+ is($("ns_id"), null, "ns getElementById " + test);
+}
+
+// Check that dynamic modifications of attribute work
+
+checkHasId("in markup");
+
+div.id = "";
+a.id = "";
+xul.id = "";
+svg.id = "";
+nsx.setAttribute("id", "");
+
+checkHasNoId(false, "set to empty");
+
+div.id = "div_id";
+a.id = "a_id";
+xul.id = "xul_id";
+svg.id = "svg_id";
+nsx.setAttribute("id", "ns_id");
+
+checkHasId("set using .id");
+
+div.setAttribute("id", "");
+a.setAttribute("id", "");
+xul.setAttribute("id", "");
+svg.setAttribute("id", "");
+nsx.setAttribute("id", "");
+
+checkHasNoId(false, "setAttribute to empty");
+
+div.id = "div_id";
+a.id = "a_id";
+xul.id = "xul_id";
+svg.id = "svg_id";
+nsx.setAttribute("id", "ns_id");
+
+checkHasId("set again using .id");
+
+div.removeAttribute("id");
+a.removeAttribute("id");
+xul.removeAttribute("id");
+svg.removeAttribute("id");
+nsx.removeAttribute("id");
+
+checkHasNoId(true, "removed attribute");
+
+div.setAttribute("id", "div_id");
+a.setAttribute("id", "a_id");
+xul.setAttribute("id", "xul_id");
+svg.setAttribute("id", "svg_id");
+nsx.setAttribute("id", "ns_id");
+
+checkHasId("set using setAttribute");
+
+t1 = document.createElement("div");
+t1.id = "div_id";
+t2 = document.createElement("a");
+t2.id = "a_id";
+t3 = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "button");
+t3.id = "xul_id";
+t4 = document.createElementNS("http://www.w3.org/2000/svg", "g");
+t4.id = "svg_id";
+t5 = document.createElementNS("urn:namespace", "ns:x");
+t5.setAttribute("id", "ns_id");
+
+// Check that inserting elements before/after existing work
+
+function insertAfter(newChild, existing) {
+ existing.parentNode.insertBefore(newChild, existing.nextSibling);
+}
+function insertBefore(newChild, existing) {
+ existing.parentNode.insertBefore(newChild, existing);
+}
+function removeNode(child) {
+ child.parentNode.removeChild(child);
+}
+
+insertAfter(t1, div);
+insertAfter(t2, a);
+insertAfter(t3, xul);
+insertAfter(t4, svg);
+insertAfter(t5, nsx);
+
+checkHasId("inserted after");
+
+insertBefore(t1, div);
+insertBefore(t2, a);
+insertBefore(t3, xul);
+insertBefore(t4, svg);
+insertBefore(t5, nsx);
+
+checkHasIdNoGEBI("inserted before");
+is($("div_id"), t1, "div getElementById inserted before");
+is($("a_id"), t2, "a getElementById inserted before");
+is($("xul_id"), t3, "xul getElementById inserted before");
+is($("svg_id"), t4, "svg getElementById inserted before");
+is($("ns_id"), t5, "ns getElementById inserted before");
+
+t1.removeAttribute("id");
+t2.removeAttribute("id");
+t3.removeAttribute("id");
+t4.removeAttribute("id");
+t5.removeAttribute("id");
+
+checkHasId("removed tx attribute");
+
+t1.setAttribute("id", "div_id");
+t2.setAttribute("id", "a_id");
+t3.setAttribute("id", "xul_id");
+t4.setAttribute("id", "svg_id");
+t5.setAttribute("id", "ns_id");
+
+checkHasIdNoGEBI("setAttribute before");
+is($("div_id"), t1, "div getElementById setAttribute before");
+is($("a_id"), t2, "a getElementById setAttribute before");
+is($("xul_id"), t3, "xul getElementById setAttribute before");
+is($("svg_id"), t4, "svg getElementById setAttribute before");
+is($("ns_id"), t5, "ns getElementById setAttribute before");
+
+removeNode(t1);
+removeNode(t2);
+removeNode(t3);
+removeNode(t4);
+removeNode(t5);
+
+checkHasId("removed temporaries");
+
+removeNode(div);
+removeNode(a);
+removeNode(xul);
+removeNode(svg);
+removeNode(nsx);
+
+checkHasIdNoGEBI("removed node");
+
+// Check that removing an element during UnsetAttr works
+is(div.id, "div_id", "div still has id set");
+var mutateFired = false;
+root.appendChild(div);
+var f = function(e) {
+ div.removeEventListener("DOMAttrModified", f, false);
+ is(e.target, div, "target is div");
+ is(div.id, "", "div no longer has id");
+ is(div.getAttribute("id"), null, "div no longer has id attr");
+ removeNode(div);
+ is(div.parentNode, null, "div was removed");
+ mutateFired = true;
+}
+div.addEventListener("DOMAttrModified", f, false);
+div.removeAttribute("id");
+ok(mutateFired, "mutation event fired");
+
+// Check same for XML elements
+is(nsx.getAttribute("id"), "ns_id", "nsx still has id set");
+mutateFired = false;
+root.appendChild(nsx);
+var f2 = function(e) {
+ nsx.removeEventListener("DOMAttrModified", f2, false);
+ is(e.target, nsx, "target is nsx");
+ is(nsx.getAttribute("id"), null, "nsx no longer has id attr");
+ removeNode(nsx);
+ is(nsx.parentNode, null, "nsx was removed");
+ mutateFired = true;
+}
+nsx.addEventListener("DOMAttrModified", f2, false);
+nsx.removeAttribute("id");
+ok(mutateFired, "mutation event fired");
+
+
+// Check that modifying the id-name of an XML element works
+ok($("ns-holder"), "ns-holder exists");
+ok($("ns2-holder"), "ns2-holder exists");
+root.appendChild(nsx);
+nsx.setAttribute("id", "ns_id");
+is(nsx_cs.color, "rgb(50, 50, 50)", "nsx has initial id");
+is($("ns_id"), nsx, "gEBI works on old id");
+nsx.setAttribute("id_2", "ns2_id");
+nsx.prefix = "ns2";
+removeNode(nsx);
+root.appendChild(nsx);
+is(nsx_cs.color, "rgb(60, 60, 60)", "nsx has new id");
+is($("ns2_id"), nsx, "gEBI works on new id");
+
+// Need to change id and then CC to ensure that we don't end up with dangling pointers
+function gc() {
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIDOMWindowUtils)
+ .garbageCollect();
+}
+ok($("ns-holder"), "ns-holder exists");
+ok($("ns2-holder"), "ns2-holder exists");
+tempNode = document.createElementNS("urn:namespace", "ns:x");
+tempNode.setAttribute("id", "tempNode_id");
+document.body.appendChild(tempNode);
+is($("tempNode_id"), tempNode, "tempNode in gEBI table");
+tempNode.prefix = "ns2";
+removeNode(tempNode);
+tempNode = null;
+gc();
+$("tempNode_id");
+ok(true, "Didn't crash when accessing old id");
+
+
+]]>
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_html_colors_quirks.html
@@ -0,0 +1,712 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=121738
+-->
+<head>
+ <meta charset="UTF-8">
+ <title>Test for Bug 121738</title>
+ <script type="application/javascript" src="/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=121738">Mozilla Bug 121738</a>
+<table id="table0"></table>
+<table id="table1"></table>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 121738 **/
+
+String.prototype.toAsciiLowerCase = function () {
+ var output = "";
+ for (var i = 0, len = this.length; i < len; ++i) {
+ if (this.charCodeAt(i) >= 0x41 && this.charCodeAt(i) <= 0x5A) {
+ output += String.fromCharCode(this.charCodeAt(i) + 0x20)
+ } else {
+ output += this.charAt(i);
+ }
+ }
+ return output;
+}
+
+var tests = [
+"#135",
+" #135",
+"#135 ",
+" #135 ",
+"# 135",
+"# 135",
+"#123456",
+" #123456",
+"#123456 ",
+" #123456 ",
+"# 123456",
+"# 123456",
+"aliceblue",
+"ALICEBLUE",
+"alıceblue",
+"alİceblue",
+" aliceblue",
+"aliceblue ",
+" aliceblue ",
+"antiquewhite",
+"aqua",
+"aquamarine",
+"azure",
+"beige",
+"bisque",
+"black",
+"blanchedalmond",
+"blue",
+"blueviolet",
+"brown",
+"burlywood",
+"cadetblue",
+"chartreuse",
+"chocolate",
+"coral",
+"cornflowerblue",
+"cornsilk",
+"crimson",
+"cyan",
+"darkblue",
+"darkcyan",
+"darkgoldenrod",
+"darkgray",
+"darkgreen",
+"darkgrey",
+"darkkhaki",
+"darkmagenta",
+"darkolivegreen",
+"darkorange",
+"darkorchid",
+"darkred",
+"darksalmon",
+"darkseagreen",
+"darkslateblue",
+"darkslategray",
+"darkslategrey",
+"darkturquoise",
+"darkviolet",
+"deeppink",
+"deepskyblue",
+"dimgray",
+"dimgrey",
+"dodgerblue",
+"firebrick",
+"floralwhite",
+"forestgreen",
+"fuchsia",
+"gainsboro",
+"ghostwhite",
+"gold",
+"goldenrod",
+"gray",
+"green",
+"greenyellow",
+"grey",
+"honeydew",
+"hotpink",
+"indianred",
+"indigo",
+"ivory",
+"khaki",
+"lavender",
+"lavenderblush",
+"lawngreen",
+"lemonchiffon",
+"lightblue",
+"lightcoral",
+"lightcyan",
+"lightgoldenrodyellow",
+"lightgray",
+"lightgreen",
+"lightgrey",
+"lightpink",
+"lightsalmon",
+"lightseagreen",
+"lightskyblue",
+"lightslategray",
+"lightslategrey",
+"lightsteelblue",
+"lightyellow",
+"lime",
+"limegreen",
+"linen",
+"magenta",
+"maroon",
+"mediumaquamarine",
+"mediumblue",
+"mediumorchid",
+"mediumpurple",
+"mediumseagreen",
+"mediumslateblue",
+"mediumspringgreen",
+"mediumturquoise",
+"mediumvioletred",
+"midnightblue",
+"mintcream",
+"mistyrose",
+"moccasin",
+"navajowhite",
+"navy",
+"oldlace",
+"olive",
+"olivedrab",
+"orange",
+"orangered",
+"orchid",
+"palegoldenrod",
+"palegreen",
+"paleturquoise",
+"palevioletred",
+"papayawhip",
+"peachpuff",
+"peru",
+"pink",
+"plum",
+"powderblue",
+"purple",
+"red",
+"rosybrown",
+"royalblue",
+"saddlebrown",
+"salmon",
+"sandybrown",
+"seagreen",
+"seashell",
+"sienna",
+"silver",
+"skyblue",
+"slateblue",
+"slategray",
+"slategrey",
+"snow",
+"springgreen",
+"steelblue",
+"tan",
+"teal",
+"thistle",
+"tomato",
+"turquoise",
+"violet",
+"wheat",
+"white",
+"whitesmoke",
+"yellow",
+"yellowgreen",
+"transparent",
+"TRANSPARENT",
+"",
+"inherit",
+"INHERIT",
+"KQ@m?-ldxNK{zH+(FL_owz>YNH^]",
+"aj9c)r+J&3)0E,- Lzv6K6nT@6?I}BY^\\g",
+"Cf}qJN|3D>m:^[7B*fhu>lC[B3\"T_-F",
+"h<s1pMd-8H[,\\caWH1oW3%M",
+"z{y]VZj)%)ZV<OTbO9\\Nbc|YL}4BI<DlUBk$EV`EbN}x/@SDN0(",
+"PSX2Ol8@",
+"d+gYXKUM'&D'S]o<9T\\:hj_i!|l!)e6R4Bo)-(965rlK\"K01C68pgkJ] fx?kjT.O&sY4",
+"[4\"tk)a/v17?0W!F`AyI[='2~;:DF6I>_<O$ he213u",
+"F|r9T&N69MWq3Jrj6",
+"dYR7}n&:Rq[J",
+"M;Z]r@(R([6aT`<sN?uO'2Kb~3U\\\\tQUDxLN1f/D(,Q0w|K;,t`,tQ~[W/c!uQg)d|:D\\U33!DK&d*C`Zc'U#",
+"kV)DKUb~h{SQCM;T*g2!Rj?>Sl=jY;3W9M{Fliu!=>tDY]5",
+"y>X\\kKN|~=J+7Pqp|%9R!nZ,@>mUW9<o;|02LV<fxihsBSKVaTdcae",
+"Q>jc|/:#qwzHL`lL%e~DbhQ+d^tpf9sx%o)jC1Nm}`G;rT2jo+M$=$?BC'|O^]hW^BBo_J->bWG1",
+"OIxA\\5HB7g3Rv;PD)z?jGe?<x`4~9&D9dSDP=ilUauI'qb",
+"aND[Al/^#;n'|V\"Vl$bh5\\G#{%y4#\\W0:ZgXe73ZuXrWcL4gr|B7,ijZZi{p)M+R9{C/&249G",
+"7xK-d6Tx]BU|T,DY.qCwusmV%Ksset",
+"I=UwM''S",
+"w|_;Qw(R:>Clf[#3JFr_+?'1D&}WaY_xaRyTpwio>C;Pjf/kIW{]KK:R&ARiP=_g_UqRVvFKG(OQo6y'wF]Fc",
+"G:",
+"+XZ%s7L3FmGFn]Y!J;.vpAUoGU,&WY8eQeGWW?Jq7ANeM}[?gsV) H\\@{8z_t$oS(_jSq]|9?W*sG%' (d%",
+"*P\"?'?NHA \\!{.S=+LD8Ltr^'=,$4uQ=tVL/T_b6m!PJ8*s*v`;6kp(+8i.}T!9p6{",
+"_@(w<\\DjMk c8/\"/ifJNT_2R>V'}{&72C2+7otvd,$M@Yqc)L=O.muEp28m&AY",
+"J!M#$z|n:+:6@7n*v)UCbkVp0;\"1#}o:i4B9oh=%'I",
+"0",
+"Krq?xAul2cRe&`*Fg2)bV/r>oJ`Z(ae,z%+`E@VkWH&`-jMZ<UW~jxDek;^j2\\Uq;C,Ss",
+"#b\\l~=y5H=#Jy(6FwH5]jU;6D",
+"YO|tw;`E_'G<d~juVPCla%K]q x\"oA-aW|Y@P$_$",
+"}rI\\5x724b29MEauSSX&!AT[J1ce?,rtLAA8X",
+"hlo8jd$D-dI=I#Be:BATkZPR~%Vfe0g_Xw^+wwhHQhC1;sn+P<b&J:~HfxVBX}9b/#HHPS",
+"+#[?UFGUVFn0Zn7yE#TEo{FV\\{6*+s+a=fR",
+"lhv.f!ENs~)?5)z:1^i@BQ|ol}9Cnkw&yV.PPx |y]@,?IL]0L_# b1'wl-]",
+"&DhZ!g%v.sF}4NoP~4<vKpaM0[12!2K!ziYC3`505I*D*J6k\\skbXJ}44J#4y2",
+"oK][N&iIV\"AEs3rIT-::L3&J^Sn42_J2yL= 2xI4o!b\"#2JiAt=",
+"^c;C^{0wD%|y~Z1X'z\\o^gI8L=@2^p3g/L6G?]Nuif;Zf15dF`IPt8",
+"62t-!*`U\\l%BFxi5B~[^~G!}h]DtXrd}y}af3",
+"?N5d9ydHPi?IhwU=41'",
+"GSZeLtA3YahI@oLy/6vT_[B`[PRZ1^.(n8`,8TyqVoCzMd!=9 e",
+"Yck5`_#NgS",
+"K9?z&o",
+"Isl2>%RB8T+,9?B{~A2{fEb[%",
+"&fV(`<ha/(T7J&X\\{YHt+5 =>%SaJ&W0_j]]\"",
+">!sQ/IYU\"Ikc\\ei;HlCcVJ\":G2/m]h1,GvOmxFOOvTUHjHu:LWE\"QU=) ",
+"7Fyx#>\"(\"N",
+"MO6\"Hd2H]r8BJ}z)%J18b<VZ5lrhI",
+"BGQ|tqdwj4};#x@?%ka[`DwgFWg*J+q/}]-\\\\-y#T",
+"zZ=JrTPxh}.(%frt58Cy=C4(*,4]:Gnz5(~iv4@u4re~6yp:zbU0(o.S+qd9eB]A5",
+"n]V3}^{9O<0cO\"rtglDO4Wc)_7Nu_JnK2EBbzRMV3b.Mj\"$9#,+-T\"N=7iPdD F<9_YWw3ZN*V;??*8VN8z?^MXi",
+"fGRSl*i>^*uy|c;5B}tKXu>5hZX:>CB{oWIrxE8@B/f{:u9]:bLO0/ZWeHoNfCc|kSh{/fXs9Y:UKaJ95vFFtB2Y",
+".&-4UOcxR\"Tbgc--@& hoUavCcQW^^fT}:I(d%o}J2t*BRA1{YGXB9>AYu^Bv#rEu`pN65_-r.IQD.?Cc/B({YtK[2KMmVOC3*2J",
+"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/",
+"8\\5tFz:sod",
+"ILUc5c!'K.7.P&=S,pSYB{",
+"%\\(6.jC\"C4\\2{TYdx,Ln^",
+"tL3HnWq q!'k!#R@2bkvIAI]hk)64-i?uk]oK(nQiKg$`m6tx|#l>m1bEK^&.X[o'b\"\\',A16n>9ZAPI9>",
+"{#Mn0,S~a\"!gw",
+"dv+6'7Dd)fz",
+"9o1*Q:{6#3f uHx\"_",
+".43_zr}X+BtruMV!H!xw 8!9I_}zlBT3W52)rh,9ngeu0o[V_s*z'8x9*yjF!",
+"y3Nm`>P:seF'V'?+<={oU5QQ",
+".#Os_jv,\"@-zsY8j'POOYnY?0ONn?i#d4tqp?~.OF#VC.=<t<+feuf{#@O7lXC@+#t_uKGue%Dk9z",
+"0Ep=zwydU-V<)9<9\\`[4,d^B&Gbo#'HTSEC;qU&1| ocNd69#{nbmYJMlj6Mfs3`w&pc(poie *ZOJIp7%}cVnfml",
+"746}e(rye4lT7#B.Or8j1->Xs@o8f0}/e>uvvkNS[3UC2F]#[>^f74jxoo&9{^ED#,CV\"k'0|xI",
+".D1{.:9gHW}]36RlUQ?!-\"0dn:+(/e@b)|'B",
+"!Nh9xY2y?5ku5f}%]JWw~OfeYdcgI#It` T)3VzYl5gChve[I'rEqyJ \"@(z.Y%fEJ:9k(",
+"J^$^L8:qI=yrerd0kxJBEwby6[>9[) NpqN%)h",
+"l&\\K{s9]aL(,dX?B\"1g1*@9BY~=UO+AWvVRI;ar4p8Tsy~Qk-=x(yp38:j|g'5H~e4",
+"(]Pe,1fTS_P%[xY96#,rwQz=P?z",
+")PC#?b'&|maJBt.6Izz%vV5e!9Sy|G!*Q",
+"pzAG^@/J&)Dc}GP*xO]ezW:*PV|Dt^fF<8GgF_1i=A\"@>nt?yOa|zS<8`/;uY~^ozjvX!K#%us!>2IYITh]Zy<^dq?&\"nqV]ZdZ",
+"T<xz*/H&}36<(4E^/Z1m<#_G0R:=qX?1`*6Y&r'SIO]9OR;m5-Zq?PU^jvLKPLW2wPf",
+")CLhmCI%TwB+t:h.@Vp-#({d0W/R_(^f34LC=V)A",
+"yCT_hl%fUL<T&e;ePsT.pJG@|jO,[pN]]Q<Yu=Lp6X6&$Ka#",
+" $4X",
+"rp",
+"t^(*U<Qdi$!vyg5D\"yQZd<K6<Qptsvzi~D}.Uf?P$E>}t8VP^;3Tamv2Z$1<",
+",",
+"EGCXZ_{eqIwfG-o7o\\\"!ZWTPLd,U-k$Cz]%:vNWdo}vDh!ONtM>mMP{/Cg+2<.J\"a*n#Rtnha",
+"LQ3sIr7Q_ wSD7Zzv$-vxr|3P`pas0#Ze/---{PSwJ3{!a*[k'nFgC\"W+@4URi?qJk&Tt@`abNms40#A^XcAt}",
+"^i356'hX\"hKaZGfTZ|C@#}b3LGz1\">qcH{L8{Fs?O5%:EqQWuro_lc=]gWLVR\\~!J\"[>,H",
+"i{*q<O{Dt^n|FY3,FG>WIRqPH.os$9^P=|yA9?P;MOw;VBwZ^>K=\"%J9SBlv%0+o5k73rW!`l_",
+"-PCM&!G~o#Za^s&)qJELr\\P^\\={_xTFp:%@JF.PeRX\\7b8K",
+"V_sFicB+wx5",
+"\"X^\\d}b9.W.2\"O!yAL21\"Ny5:)=Q3*D|TAzzr^0Yflzjdc!p*.yW,B",
+"kZ`wCP>9Bq5S!r!Vi|Uy/C&H[kz/f^{(Z[OGw'S0\"",
+"Jn%1^rUnNB|%=q%^v*bN|I40}#Htn{G!#~CNAN0KvZcB>Ita(,n",
+"-PlhE[^J55Ui",
+"z`h`uQJ{J",
+"eV\\q5Q4o@Y*,IRMcnpqj5>Id\\yBe?pKH3uF&c<c}:E9[uaH$ 8dXCmI+!C'q@PkE<NVRq~GRW<tfyt/i@%dwI&rL",
+"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA",
+"&joOSw7XZVvSt4ZCT*:aq:3ns!v|r);~7gN8'_D",
+"Y<q|Mhn5Nrcb+dR=10pQF5]r@/*7P`79w/htSm2,C~1&sUW{N@v:t9d;HPG&xrI\"YD;V9Y$'g,W'J=GV3,YK",
+"Gx&#{;]l/?[{SyX`kTeo",
+"30PU7@<'58.hRWsJTa9L.hVQ8}7=$}ih4|$Y*9z3[aooT!]}+>b{1JH^.jjEU{,dAXSCbtEh6",
+"%2~x8=A!RW@8N/`hQz`)gl}1DOU9{>Ie'L> 4e]m;kt =isEQ(\\TeI7hWgK-K! p^K'\":3;dxTLO",
+"\\ ):{Woay[4",
+"\\{Ih&}*8^x6@`V@DZB`rSuhYm4i@TW^t9Hx[^`IVumjXc1vA\"~wt8^Jf:US6Z\\xaS&",
+"lo $6<EP|=gAEpd\\M6YDg\"*0m",
+/*
+"ActiveBorder",
+"ActiveCaption",
+"AppWorkspace",
+"Background",
+"ButtonFace",
+"ButtonHighlight",
+"ButtonShadow",
+"ButtonText",
+"CaptionText",
+"GrayText",
+"Highlight",
+"HighlightText",
+"InactiveBorder",
+"InactiveCaption",
+"InactiveCaptionText",
+"InfoBackground",
+"InfoText",
+"Menu",
+"MenuText",
+"Scrollbar",
+"ThreeDDarkShadow",
+"ThreeDFace",
+"ThreeDHighlight",
+"ThreeDLightShadow",
+"ThreeDShadow",
+"Window",
+"WindowFrame",
+"WindowText",
+*/
+"currentColor",
+"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"#000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"#0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"#",
+"#1",
+"#12",
+"#123",
+"#1234",
+"#12x",
+"abc",
+"123",
+"#0ab0cd0ef",
+"#0ab0cd0e",
+"#0ab0cd0",
+"#0ab0cdaef",
+"#0ab0cdae",
+"#0ab0cda"
+];
+
+var references = [
+"#113355",
+"#001350",
+"#135000",
+"#001350",
+"#013500",
+"#000135",
+"#123456",
+"#002356",
+"#124500",
+"#002356",
+"#013460",
+"#001245",
+"#f0f8ff",
+"#f0f8ff",
+"#a0ce00",
+"#a0ce00",
+"#0ace0e",
+"#a0ebe0",
+"#00cee0",
+"#faebd7",
+"#00ffff",
+"#7fffd4",
+"#f0ffff",
+"#f5f5dc",
+"#ffe4c4",
+"#000000",
+"#ffebcd",
+"#0000ff",
+"#8a2be2",
+"#a52a2a",
+"#deb887",
+"#5f9ea0",
+"#7fff00",
+"#d2691e",
+"#ff7f50",
+"#6495ed",
+"#fff8dc",
+"#dc143c",
+"#00ffff",
+"#00008b",
+"#008b8b",
+"#b8860b",
+"#a9a9a9",
+"#006400",
+"#a9a9a9",
+"#bdb76b",
+"#8b008b",
+"#556b2f",
+"#ff8c00",
+"#9932cc",
+"#8b0000",
+"#e9967a",
+"#8fbc8f",
+"#483d8b",
+"#2f4f4f",
+"#2f4f4f",
+"#00ced1",
+"#9400d3",
+"#ff1493",
+"#00bfff",
+"#696969",
+"#696969",
+"#1e90ff",
+"#b22222",
+"#fffaf0",
+"#228b22",
+"#ff00ff",
+"#dcdcdc",
+"#f8f8ff",
+"#ffd700",
+"#daa520",
+"#808080",
+"#008000",
+"#adff2f",
+"#808080",
+"#f0fff0",
+"#ff69b4",
+"#cd5c5c",
+"#4b0082",
+"#fffff0",
+"#f0e68c",
+"#e6e6fa",
+"#fff0f5",
+"#7cfc00",
+"#fffacd",
+"#add8e6",
+"#f08080",
+"#e0ffff",
+"#fafad2",
+"#d3d3d3",
+"#90ee90",
+"#d3d3d3",
+"#ffb6c1",
+"#ffa07a",
+"#20b2aa",
+"#87cefa",
+"#778899",
+"#778899",
+"#b0c4de",
+"#ffffe0",
+"#00ff00",
+"#32cd32",
+"#faf0e6",
+"#ff00ff",
+"#800000",
+"#66cdaa",
+"#0000cd",
+"#ba55d3",
+"#9370db",
+"#3cb371",
+"#7b68ee",
+"#00fa9a",
+"#48d1cc",
+"#c71585",
+"#191970",
+"#f5fffa",
+"#ffe4e1",
+"#ffe4b5",
+"#ffdead",
+"#000080",
+"#fdf5e6",
+"#808000",
+"#6b8e23",
+"#ffa500",
+"#ff4500",
+"#da70d6",
+"#eee8aa",
+"#98fb98",
+"#afeeee",
+"#db7093",
+"#ffefd5",
+"#ffdab9",
+"#cd853f",
+"#ffc0cb",
+"#dda0dd",
+"#b0e0e6",
+"#800080",
+"#ff0000",
+"#bc8f8f",
+"#4169e1",
+"#8b4513",
+"#fa8072",
+"#f4a460",
+"#2e8b57",
+"#fff5ee",
+"#a0522d",
+"#c0c0c0",
+"#87ceeb",
+"#6a5acd",
+"#708090",
+"#708090",
+"#fffafa",
+"#00ff7f",
+"#4682b4",
+"#d2b48c",
+"#008080",
+"#d8bfd8",
+"#ff6347",
+"#40e0d0",
+"#ee82ee",
+"#f5deb3",
+"#ffffff",
+"#f5f5f5",
+"#ffff00",
+"#9acd32",
+"transparent",
+"transparent",
+"transparent",
+"#00e000",
+"#00e000",
+"#0df000",
+"#0000b0",
+"#007b30",
+"#008001",
+"#004b00",
+"#002080",
+"#099600",
+"#0120e2",
+"#f00630",
+"#d00000",
+"#200000",
+"#0c00d0",
+"#07900a",
+"#db020b",
+"#7000a0",
+"#b00c02",
+"#d6d000",
+"#000000",
+"#1d00f0",
+"#000000",
+"#a00000",
+"#00b600",
+"#007028",
+"#00b0b9",
+"#000000",
+"#f00000",
+"#b00005",
+"#0ea000",
+"#72000a",
+"#ba0c00",
+"#0fe000",
+"#50000b",
+"#000c44",
+"#ae4202",
+"#00005d",
+"#0000af",
+"#5d0041",
+"#a00000",
+"#c00000",
+"#090000",
+"#0209fe",
+"#a00500",
+"#c0100e",
+"#7f0000",
+"#600000",
+"#d00d00",
+"#0004d9",
+"#c00000",
+"#0500ff",
+"#0000c3",
+"#200000",
+"#80f00d",
+"#0c7000",
+"#00c4d0",
+"#a000a0",
+"#00a000",
+"#d0070f",
+"#900600",
+"#002090",
+"#30ef00",
+"#0000e0",
+"#b000c0",
+"#80c200",
+"#0900e0",
+"#0005e0",
+"#800b00",
+"#b0a000",
+"#e00000",
+"#000690",
+"#d00000",
+"#010020",
+"#0000c0",
+"#000060",
+"#004000",
+"#000000",
+"#000da0",
+"#000000",
+"#00d000",
+"#000fa0",
+"#0c5000",
+"#000030",
+"#a0007b",
+"#00cb05",
+"#023000",
+"#9bc000",
+"#b000b0",
+"#00e055",
+"#000000",
+"#0dc0d0",
+"#20600a",
+"#70a070",
+"#f50000",
+"#0000e0",
+"#a900cb",
+"#0000d0",
+"#000a40",
+"#d00060",
+"#000ad0",
+/*
+"ActiveBorder",
+"ActiveCaption",
+"AppWorkspace",
+"Background",
+"ButtonFace",
+"ButtonHighlight",
+"ButtonShadow",
+"ButtonText",
+"CaptionText",
+"GrayText",
+"Highlight",
+"HighlightText",
+"InactiveBorder",
+"InactiveCaption",
+"InactiveCaptionText",
+"InfoBackground",
+"InfoText",
+"Menu",
+"MenuText",
+"Scrollbar",
+"ThreeDDarkShadow",
+"ThreeDFace",
+"ThreeDHighlight",
+"ThreeDLightShadow",
+"ThreeDShadow",
+"Window",
+"WindowFrame",
+"WindowText",
+*/
+"#c0e000",
+"#0000f0",
+"#000000",
+"#0000f0",
+"#000000",
+"#000000",
+"#010000",
+"#010200",
+"#112233",
+"#123400",
+"#010200",
+"#0a0b0c",
+"#010203",
+"#abcdef",
+"#abcde0",
+"#abcd00",
+"#0a0cae",
+"#0a0cae",
+"#0a0ca0"
+];
+
+var todos = {
+" #135": true,
+"#135 ": true,
+" #135 ": true,
+"# 135": true,
+" #123456": true,
+"#123456 ": true,
+" #123456 ": true,
+"# 123456": true,
+" aliceblue": true,
+"aliceblue ": true,
+" aliceblue ": true,
+"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/": true,
+" $4X": true,
+"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA": true
+};
+
+var table0 = document.getElementById("table0");
+var table1 = document.getElementById("table1");
+var cs0 = document.defaultView.getComputedStyle(table0, "");
+var cs1 = document.defaultView.getComputedStyle(table1, "");
+var result;
+var reference;
+var log = "";
+var len = tests.length;
+is(tests.length, references.length, "array length mismatch");
+for (var i = 0; i < len; ++i) {
+ table0.setAttribute("bgColor", tests[i]);
+ table1.style.backgroundColor = references[i];
+ ((tests[i] in todos) ? todo_is : is)(
+ cs0.getPropertyValue("background-color"),
+ cs1.getPropertyValue("background-color"),
+ "html color '" + tests[i] + "' should match '" + references[i] + "'");
+}
+</script>
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_html_colors_standards.html
@@ -0,0 +1,713 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=121738
+-->
+<head>
+ <meta charset="UTF-8">
+ <title>Test for Bug 121738</title>
+ <script type="application/javascript" src="/MochiKit/packed.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=121738">Mozilla Bug 121738</a>
+<table id="table0"></table>
+<table id="table1"></table>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 121738 **/
+
+String.prototype.toAsciiLowerCase = function () {
+ var output = "";
+ for (var i = 0, len = this.length; i < len; ++i) {
+ if (this.charCodeAt(i) >= 0x41 && this.charCodeAt(i) <= 0x5A) {
+ output += String.fromCharCode(this.charCodeAt(i) + 0x20)
+ } else {
+ output += this.charAt(i);
+ }
+ }
+ return output;
+}
+
+var tests = [
+"#135",
+" #135",
+"#135 ",
+" #135 ",
+"# 135",
+"# 135",
+"#123456",
+" #123456",
+"#123456 ",
+" #123456 ",
+"# 123456",
+"# 123456",
+"aliceblue",
+"ALICEBLUE",
+"alıceblue",
+"alİceblue",
+" aliceblue",
+"aliceblue ",
+" aliceblue ",
+"antiquewhite",
+"aqua",
+"aquamarine",
+"azure",
+"beige",
+"bisque",
+"black",
+"blanchedalmond",
+"blue",
+"blueviolet",
+"brown",
+"burlywood",
+"cadetblue",
+"chartreuse",
+"chocolate",
+"coral",
+"cornflowerblue",
+"cornsilk",
+"crimson",
+"cyan",
+"darkblue",
+"darkcyan",
+"darkgoldenrod",
+"darkgray",
+"darkgreen",
+"darkgrey",
+"darkkhaki",
+"darkmagenta",
+"darkolivegreen",
+"darkorange",
+"darkorchid",
+"darkred",
+"darksalmon",
+"darkseagreen",
+"darkslateblue",
+"darkslategray",
+"darkslategrey",
+"darkturquoise",
+"darkviolet",
+"deeppink",
+"deepskyblue",
+"dimgray",
+"dimgrey",
+"dodgerblue",
+"firebrick",
+"floralwhite",
+"forestgreen",
+"fuchsia",
+"gainsboro",
+"ghostwhite",
+"gold",
+"goldenrod",
+"gray",
+"green",
+"greenyellow",
+"grey",
+"honeydew",
+"hotpink",
+"indianred",
+"indigo",
+"ivory",
+"khaki",
+"lavender",
+"lavenderblush",
+"lawngreen",
+"lemonchiffon",
+"lightblue",
+"lightcoral",
+"lightcyan",
+"lightgoldenrodyellow",
+"lightgray",
+"lightgreen",
+"lightgrey",
+"lightpink",
+"lightsalmon",
+"lightseagreen",
+"lightskyblue",
+"lightslategray",
+"lightslategrey",
+"lightsteelblue",
+"lightyellow",
+"lime",
+"limegreen",
+"linen",
+"magenta",
+"maroon",
+"mediumaquamarine",
+"mediumblue",
+"mediumorchid",
+"mediumpurple",
+"mediumseagreen",
+"mediumslateblue",
+"mediumspringgreen",
+"mediumturquoise",
+"mediumvioletred",
+"midnightblue",
+"mintcream",
+"mistyrose",
+"moccasin",
+"navajowhite",
+"navy",
+"oldlace",
+"olive",
+"olivedrab",
+"orange",
+"orangered",
+"orchid",
+"palegoldenrod",
+"palegreen",
+"paleturquoise",
+"palevioletred",
+"papayawhip",
+"peachpuff",
+"peru",
+"pink",
+"plum",
+"powderblue",
+"purple",
+"red",
+"rosybrown",
+"royalblue",
+"saddlebrown",
+"salmon",
+"sandybrown",
+"seagreen",
+"seashell",
+"sienna",
+"silver",
+"skyblue",
+"slateblue",
+"slategray",
+"slategrey",
+"snow",
+"springgreen",
+"steelblue",
+"tan",
+"teal",
+"thistle",
+"tomato",
+"turquoise",
+"violet",
+"wheat",
+"white",
+"whitesmoke",
+"yellow",
+"yellowgreen",
+"transparent",
+"TRANSPARENT",
+"",
+"inherit",
+"INHERIT",
+"KQ@m?-ldxNK{zH+(FL_owz>YNH^]",
+"aj9c)r+J&3)0E,- Lzv6K6nT@6?I}BY^\\g",
+"Cf}qJN|3D>m:^[7B*fhu>lC[B3\"T_-F",
+"h<s1pMd-8H[,\\caWH1oW3%M",
+"z{y]VZj)%)ZV<OTbO9\\Nbc|YL}4BI<DlUBk$EV`EbN}x/@SDN0(",
+"PSX2Ol8@",
+"d+gYXKUM'&D'S]o<9T\\:hj_i!|l!)e6R4Bo)-(965rlK\"K01C68pgkJ] fx?kjT.O&sY4",
+"[4\"tk)a/v17?0W!F`AyI[='2~;:DF6I>_<O$ he213u",
+"F|r9T&N69MWq3Jrj6",
+"dYR7}n&:Rq[J",
+"M;Z]r@(R([6aT`<sN?uO'2Kb~3U\\\\tQUDxLN1f/D(,Q0w|K;,t`,tQ~[W/c!uQg)d|:D\\U33!DK&d*C`Zc'U#",
+"kV)DKUb~h{SQCM;T*g2!Rj?>Sl=jY;3W9M{Fliu!=>tDY]5",
+"y>X\\kKN|~=J+7Pqp|%9R!nZ,@>mUW9<o;|02LV<fxihsBSKVaTdcae",
+"Q>jc|/:#qwzHL`lL%e~DbhQ+d^tpf9sx%o)jC1Nm}`G;rT2jo+M$=$?BC'|O^]hW^BBo_J->bWG1",
+"OIxA\\5HB7g3Rv;PD)z?jGe?<x`4~9&D9dSDP=ilUauI'qb",
+"aND[Al/^#;n'|V\"Vl$bh5\\G#{%y4#\\W0:ZgXe73ZuXrWcL4gr|B7,ijZZi{p)M+R9{C/&249G",
+"7xK-d6Tx]BU|T,DY.qCwusmV%Ksset",
+"I=UwM''S",
+"w|_;Qw(R:>Clf[#3JFr_+?'1D&}WaY_xaRyTpwio>C;Pjf/kIW{]KK:R&ARiP=_g_UqRVvFKG(OQo6y'wF]Fc",
+"G:",
+"+XZ%s7L3FmGFn]Y!J;.vpAUoGU,&WY8eQeGWW?Jq7ANeM}[?gsV) H\\@{8z_t$oS(_jSq]|9?W*sG%' (d%",
+"*P\"?'?NHA \\!{.S=+LD8Ltr^'=,$4uQ=tVL/T_b6m!PJ8*s*v`;6kp(+8i.}T!9p6{",
+"_@(w<\\DjMk c8/\"/ifJNT_2R>V'}{&72C2+7otvd,$M@Yqc)L=O.muEp28m&AY",
+"J!M#$z|n:+:6@7n*v)UCbkVp0;\"1#}o:i4B9oh=%'I",
+"0",
+"Krq?xAul2cRe&`*Fg2)bV/r>oJ`Z(ae,z%+`E@VkWH&`-jMZ<UW~jxDek;^j2\\Uq;C,Ss",
+"#b\\l~=y5H=#Jy(6FwH5]jU;6D",
+"YO|tw;`E_'G<d~juVPCla%K]q x\"oA-aW|Y@P$_$",
+"}rI\\5x724b29MEauSSX&!AT[J1ce?,rtLAA8X",
+"hlo8jd$D-dI=I#Be:BATkZPR~%Vfe0g_Xw^+wwhHQhC1;sn+P<b&J:~HfxVBX}9b/#HHPS",
+"+#[?UFGUVFn0Zn7yE#TEo{FV\\{6*+s+a=fR",
+"lhv.f!ENs~)?5)z:1^i@BQ|ol}9Cnkw&yV.PPx |y]@,?IL]0L_# b1'wl-]",
+"&DhZ!g%v.sF}4NoP~4<vKpaM0[12!2K!ziYC3`505I*D*J6k\\skbXJ}44J#4y2",
+"oK][N&iIV\"AEs3rIT-::L3&J^Sn42_J2yL= 2xI4o!b\"#2JiAt=",
+"^c;C^{0wD%|y~Z1X'z\\o^gI8L=@2^p3g/L6G?]Nuif;Zf15dF`IPt8",
+"62t-!*`U\\l%BFxi5B~[^~G!}h]DtXrd}y}af3",
+"?N5d9ydHPi?IhwU=41'",
+"GSZeLtA3YahI@oLy/6vT_[B`[PRZ1^.(n8`,8TyqVoCzMd!=9 e",
+"Yck5`_#NgS",
+"K9?z&o",
+"Isl2>%RB8T+,9?B{~A2{fEb[%",
+"&fV(`<ha/(T7J&X\\{YHt+5 =>%SaJ&W0_j]]\"",
+">!sQ/IYU\"Ikc\\ei;HlCcVJ\":G2/m]h1,GvOmxFOOvTUHjHu:LWE\"QU=) ",
+"7Fyx#>\"(\"N",
+"MO6\"Hd2H]r8BJ}z)%J18b<VZ5lrhI",
+"BGQ|tqdwj4};#x@?%ka[`DwgFWg*J+q/}]-\\\\-y#T",
+"zZ=JrTPxh}.(%frt58Cy=C4(*,4]:Gnz5(~iv4@u4re~6yp:zbU0(o.S+qd9eB]A5",
+"n]V3}^{9O<0cO\"rtglDO4Wc)_7Nu_JnK2EBbzRMV3b.Mj\"$9#,+-T\"N=7iPdD F<9_YWw3ZN*V;??*8VN8z?^MXi",
+"fGRSl*i>^*uy|c;5B}tKXu>5hZX:>CB{oWIrxE8@B/f{:u9]:bLO0/ZWeHoNfCc|kSh{/fXs9Y:UKaJ95vFFtB2Y",
+".&-4UOcxR\"Tbgc--@& hoUavCcQW^^fT}:I(d%o}J2t*BRA1{YGXB9>AYu^Bv#rEu`pN65_-r.IQD.?Cc/B({YtK[2KMmVOC3*2J",
+"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/",
+"8\\5tFz:sod",
+"ILUc5c!'K.7.P&=S,pSYB{",
+"%\\(6.jC\"C4\\2{TYdx,Ln^",
+"tL3HnWq q!'k!#R@2bkvIAI]hk)64-i?uk]oK(nQiKg$`m6tx|#l>m1bEK^&.X[o'b\"\\',A16n>9ZAPI9>",
+"{#Mn0,S~a\"!gw",
+"dv+6'7Dd)fz",
+"9o1*Q:{6#3f uHx\"_",
+".43_zr}X+BtruMV!H!xw 8!9I_}zlBT3W52)rh,9ngeu0o[V_s*z'8x9*yjF!",
+"y3Nm`>P:seF'V'?+<={oU5QQ",
+".#Os_jv,\"@-zsY8j'POOYnY?0ONn?i#d4tqp?~.OF#VC.=<t<+feuf{#@O7lXC@+#t_uKGue%Dk9z",
+"0Ep=zwydU-V<)9<9\\`[4,d^B&Gbo#'HTSEC;qU&1| ocNd69#{nbmYJMlj6Mfs3`w&pc(poie *ZOJIp7%}cVnfml",
+"746}e(rye4lT7#B.Or8j1->Xs@o8f0}/e>uvvkNS[3UC2F]#[>^f74jxoo&9{^ED#,CV\"k'0|xI",
+".D1{.:9gHW}]36RlUQ?!-\"0dn:+(/e@b)|'B",
+"!Nh9xY2y?5ku5f}%]JWw~OfeYdcgI#It` T)3VzYl5gChve[I'rEqyJ \"@(z.Y%fEJ:9k(",
+"J^$^L8:qI=yrerd0kxJBEwby6[>9[) NpqN%)h",
+"l&\\K{s9]aL(,dX?B\"1g1*@9BY~=UO+AWvVRI;ar4p8Tsy~Qk-=x(yp38:j|g'5H~e4",
+"(]Pe,1fTS_P%[xY96#,rwQz=P?z",
+")PC#?b'&|maJBt.6Izz%vV5e!9Sy|G!*Q",
+"pzAG^@/J&)Dc}GP*xO]ezW:*PV|Dt^fF<8GgF_1i=A\"@>nt?yOa|zS<8`/;uY~^ozjvX!K#%us!>2IYITh]Zy<^dq?&\"nqV]ZdZ",
+"T<xz*/H&}36<(4E^/Z1m<#_G0R:=qX?1`*6Y&r'SIO]9OR;m5-Zq?PU^jvLKPLW2wPf",
+")CLhmCI%TwB+t:h.@Vp-#({d0W/R_(^f34LC=V)A",
+"yCT_hl%fUL<T&e;ePsT.pJG@|jO,[pN]]Q<Yu=Lp6X6&$Ka#",
+" $4X",
+"rp",
+"t^(*U<Qdi$!vyg5D\"yQZd<K6<Qptsvzi~D}.Uf?P$E>}t8VP^;3Tamv2Z$1<",
+",",
+"EGCXZ_{eqIwfG-o7o\\\"!ZWTPLd,U-k$Cz]%:vNWdo}vDh!ONtM>mMP{/Cg+2<.J\"a*n#Rtnha",
+"LQ3sIr7Q_ wSD7Zzv$-vxr|3P`pas0#Ze/---{PSwJ3{!a*[k'nFgC\"W+@4URi?qJk&Tt@`abNms40#A^XcAt}",
+"^i356'hX\"hKaZGfTZ|C@#}b3LGz1\">qcH{L8{Fs?O5%:EqQWuro_lc=]gWLVR\\~!J\"[>,H",
+"i{*q<O{Dt^n|FY3,FG>WIRqPH.os$9^P=|yA9?P;MOw;VBwZ^>K=\"%J9SBlv%0+o5k73rW!`l_",
+"-PCM&!G~o#Za^s&)qJELr\\P^\\={_xTFp:%@JF.PeRX\\7b8K",
+"V_sFicB+wx5",
+"\"X^\\d}b9.W.2\"O!yAL21\"Ny5:)=Q3*D|TAzzr^0Yflzjdc!p*.yW,B",
+"kZ`wCP>9Bq5S!r!Vi|Uy/C&H[kz/f^{(Z[OGw'S0\"",
+"Jn%1^rUnNB|%=q%^v*bN|I40}#Htn{G!#~CNAN0KvZcB>Ita(,n",
+"-PlhE[^J55Ui",
+"z`h`uQJ{J",
+"eV\\q5Q4o@Y*,IRMcnpqj5>Id\\yBe?pKH3uF&c<c}:E9[uaH$ 8dXCmI+!C'q@PkE<NVRq~GRW<tfyt/i@%dwI&rL",
+"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA",
+"&joOSw7XZVvSt4ZCT*:aq:3ns!v|r);~7gN8'_D",
+"Y<q|Mhn5Nrcb+dR=10pQF5]r@/*7P`79w/htSm2,C~1&sUW{N@v:t9d;HPG&xrI\"YD;V9Y$'g,W'J=GV3,YK",
+"Gx&#{;]l/?[{SyX`kTeo",
+"30PU7@<'58.hRWsJTa9L.hVQ8}7=$}ih4|$Y*9z3[aooT!]}+>b{1JH^.jjEU{,dAXSCbtEh6",
+"%2~x8=A!RW@8N/`hQz`)gl}1DOU9{>Ie'L> 4e]m;kt =isEQ(\\TeI7hWgK-K! p^K'\":3;dxTLO",
+"\\ ):{Woay[4",
+"\\{Ih&}*8^x6@`V@DZB`rSuhYm4i@TW^t9Hx[^`IVumjXc1vA\"~wt8^Jf:US6Z\\xaS&",
+"lo $6<EP|=gAEpd\\M6YDg\"*0m",
+/*
+"ActiveBorder",
+"ActiveCaption",
+"AppWorkspace",
+"Background",
+"ButtonFace",
+"ButtonHighlight",
+"ButtonShadow",
+"ButtonText",
+"CaptionText",
+"GrayText",
+"Highlight",
+"HighlightText",
+"InactiveBorder",
+"InactiveCaption",
+"InactiveCaptionText",
+"InfoBackground",
+"InfoText",
+"Menu",
+"MenuText",
+"Scrollbar",
+"ThreeDDarkShadow",
+"ThreeDFace",
+"ThreeDHighlight",
+"ThreeDLightShadow",
+"ThreeDShadow",
+"Window",
+"WindowFrame",
+"WindowText",
+*/
+"currentColor",
+"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"#000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"#0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f",
+"#",
+"#1",
+"#12",
+"#123",
+"#1234",
+"#12x",
+"abc",
+"123",
+"#0ab0cd0ef",
+"#0ab0cd0e",
+"#0ab0cd0",
+"#0ab0cdaef",
+"#0ab0cdae",
+"#0ab0cda"
+];
+
+var references = [
+"#113355",
+"#001350",
+"#135000",
+"#001350",
+"#013500",
+"#000135",
+"#123456",
+"#002356",
+"#124500",
+"#002356",
+"#013460",
+"#001245",
+"#f0f8ff",
+"#f0f8ff",
+"#a0ce00",
+"#a0ce00",
+"#0ace0e",
+"#a0ebe0",
+"#00cee0",
+"#faebd7",
+"#00ffff",
+"#7fffd4",
+"#f0ffff",
+"#f5f5dc",
+"#ffe4c4",
+"#000000",
+"#ffebcd",
+"#0000ff",
+"#8a2be2",
+"#a52a2a",
+"#deb887",
+"#5f9ea0",
+"#7fff00",
+"#d2691e",
+"#ff7f50",
+"#6495ed",
+"#fff8dc",
+"#dc143c",
+"#00ffff",
+"#00008b",
+"#008b8b",
+"#b8860b",
+"#a9a9a9",
+"#006400",
+"#a9a9a9",
+"#bdb76b",
+"#8b008b",
+"#556b2f",
+"#ff8c00",
+"#9932cc",
+"#8b0000",
+"#e9967a",
+"#8fbc8f",
+"#483d8b",
+"#2f4f4f",
+"#2f4f4f",
+"#00ced1",
+"#9400d3",
+"#ff1493",
+"#00bfff",
+"#696969",
+"#696969",
+"#1e90ff",
+"#b22222",
+"#fffaf0",
+"#228b22",
+"#ff00ff",
+"#dcdcdc",
+"#f8f8ff",
+"#ffd700",
+"#daa520",
+"#808080",
+"#008000",
+"#adff2f",
+"#808080",
+"#f0fff0",
+"#ff69b4",
+"#cd5c5c",
+"#4b0082",
+"#fffff0",
+"#f0e68c",
+"#e6e6fa",
+"#fff0f5",
+"#7cfc00",
+"#fffacd",
+"#add8e6",
+"#f08080",
+"#e0ffff",
+"#fafad2",
+"#d3d3d3",
+"#90ee90",
+"#d3d3d3",
+"#ffb6c1",
+"#ffa07a",
+"#20b2aa",
+"#87cefa",
+"#778899",
+"#778899",
+"#b0c4de",
+"#ffffe0",
+"#00ff00",
+"#32cd32",
+"#faf0e6",
+"#ff00ff",
+"#800000",
+"#66cdaa",
+"#0000cd",
+"#ba55d3",
+"#9370db",
+"#3cb371",
+"#7b68ee",
+"#00fa9a",
+"#48d1cc",
+"#c71585",
+"#191970",
+"#f5fffa",
+"#ffe4e1",
+"#ffe4b5",
+"#ffdead",
+"#000080",
+"#fdf5e6",
+"#808000",
+"#6b8e23",
+"#ffa500",
+"#ff4500",
+"#da70d6",
+"#eee8aa",
+"#98fb98",
+"#afeeee",
+"#db7093",
+"#ffefd5",
+"#ffdab9",
+"#cd853f",
+"#ffc0cb",
+"#dda0dd",
+"#b0e0e6",
+"#800080",
+"#ff0000",
+"#bc8f8f",
+"#4169e1",
+"#8b4513",
+"#fa8072",
+"#f4a460",
+"#2e8b57",
+"#fff5ee",
+"#a0522d",
+"#c0c0c0",
+"#87ceeb",
+"#6a5acd",
+"#708090",
+"#708090",
+"#fffafa",
+"#00ff7f",
+"#4682b4",
+"#d2b48c",
+"#008080",
+"#d8bfd8",
+"#ff6347",
+"#40e0d0",
+"#ee82ee",
+"#f5deb3",
+"#ffffff",
+"#f5f5f5",
+"#ffff00",
+"#9acd32",
+"transparent",
+"transparent",
+"transparent",
+"#00e000",
+"#00e000",
+"#0df000",
+"#0000b0",
+"#007b30",
+"#008001",
+"#004b00",
+"#002080",
+"#099600",
+"#0120e2",
+"#f00630",
+"#d00000",
+"#200000",
+"#0c00d0",
+"#07900a",
+"#db020b",
+"#7000a0",
+"#b00c02",
+"#d6d000",
+"#000000",
+"#1d00f0",
+"#000000",
+"#a00000",
+"#00b600",
+"#007028",
+"#00b0b9",
+"#000000",
+"#f00000",
+"#b00005",
+"#0ea000",
+"#72000a",
+"#ba0c00",
+"#0fe000",
+"#50000b",
+"#000c44",
+"#ae4202",
+"#00005d",
+"#0000af",
+"#5d0041",
+"#a00000",
+"#c00000",
+"#090000",
+"#0209fe",
+"#a00500",
+"#c0100e",
+"#7f0000",
+"#600000",
+"#d00d00",
+"#0004d9",
+"#c00000",
+"#0500ff",
+"#0000c3",
+"#200000",
+"#80f00d",
+"#0c7000",
+"#00c4d0",
+"#a000a0",
+"#00a000",
+"#d0070f",
+"#900600",
+"#002090",
+"#30ef00",
+"#0000e0",
+"#b000c0",
+"#80c200",
+"#0900e0",
+"#0005e0",
+"#800b00",
+"#b0a000",
+"#e00000",
+"#000690",
+"#d00000",
+"#010020",
+"#0000c0",
+"#000060",
+"#004000",
+"#000000",
+"#000da0",
+"#000000",
+"#00d000",
+"#000fa0",
+"#0c5000",
+"#000030",
+"#a0007b",
+"#00cb05",
+"#023000",
+"#9bc000",
+"#b000b0",
+"#00e055",
+"#000000",
+"#0dc0d0",
+"#20600a",
+"#70a070",
+"#f50000",
+"#0000e0",
+"#a900cb",
+"#0000d0",
+"#000a40",
+"#d00060",
+"#000ad0",
+/*
+"ActiveBorder",
+"ActiveCaption",
+"AppWorkspace",
+"Background",
+"ButtonFace",
+"ButtonHighlight",
+"ButtonShadow",
+"ButtonText",
+"CaptionText",
+"GrayText",
+"Highlight",
+"HighlightText",
+"InactiveBorder",
+"InactiveCaption",
+"InactiveCaptionText",
+"InfoBackground",
+"InfoText",
+"Menu",
+"MenuText",
+"Scrollbar",
+"ThreeDDarkShadow",
+"ThreeDFace",
+"ThreeDHighlight",
+"ThreeDLightShadow",
+"ThreeDShadow",
+"Window",
+"WindowFrame",
+"WindowText",
+*/
+"#c0e000",
+"#0000f0",
+"#000000",
+"#0000f0",
+"#000000",
+"#000000",
+"#010000",
+"#010200",
+"#112233",
+"#123400",
+"#010200",
+"#0a0b0c",
+"#010203",
+"#abcdef",
+"#abcde0",
+"#abcd00",
+"#0a0cae",
+"#0a0cae",
+"#0a0ca0"
+];
+
+var todos = {
+" #135": true,
+"#135 ": true,
+" #135 ": true,
+"# 135": true,
+" #123456": true,
+"#123456 ": true,
+" #123456 ": true,
+"# 123456": true,
+" aliceblue": true,
+"aliceblue ": true,
+" aliceblue ": true,
+"H3<MOq'81C#\\nUjQc xlsF@c2R<e);T~G]^N0_*M<j!jub~k,mgZ(.>GERhwS;kmmKC?1l} qQ&zcXK?g)S OmF^=E^TlTC)/": true,
+" $4X": true,
+"UGzLF+o3)Ezs=nMxqd^\"=q.Ik}Tk2I`X)R8]Zmy/WQp,|]TdbP)5 J+#Hm6SmWtQ+h?.MQ1W#oyp\\F,'JL>rLtjiHOA": true
+};
+
+var table0 = document.getElementById("table0");
+var table1 = document.getElementById("table1");
+var cs0 = document.defaultView.getComputedStyle(table0, "");
+var cs1 = document.defaultView.getComputedStyle(table1, "");
+var result;
+var reference;
+var log = "";
+var len = tests.length;
+is(tests.length, references.length, "array length mismatch");
+for (var i = 0; i < len; ++i) {
+ table0.setAttribute("bgColor", tests[i]);
+ table1.style.backgroundColor = references[i];
+ ((tests[i] in todos) ? todo_is : is)(
+ cs0.getPropertyValue("background-color"),
+ cs1.getPropertyValue("background-color"),
+ "html color '" + tests[i] + "' should match '" + references[i] + "'");
+}
+</script>
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/canvas/src/WebGLContextNotSupported.cpp
+++ b/content/canvas/src/WebGLContextNotSupported.cpp
@@ -45,8 +45,9 @@ DUMMY(NS_NewCanvasRenderingContextWebGL,
DOMCI_DATA(CanvasRenderingContextWebGL, void)
DOMCI_DATA(WebGLBuffer, void)
DOMCI_DATA(WebGLTexture, void)
DOMCI_DATA(WebGLProgram, void)
DOMCI_DATA(WebGLShader, void)
DOMCI_DATA(WebGLFramebuffer, void)
DOMCI_DATA(WebGLRenderbuffer, void)
+DOMCI_DATA(WebGLUniformLocation, void)
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -908,30 +908,34 @@ nsGenericHTMLElement::UpdateEditableStat
// XXX Should we do this only when in a document?
ContentEditableTristate value = GetContentEditableValue();
if (value != eInherit) {
SetEditableFlag(!!value);
return;
}
- nsGenericElement::UpdateEditableState();
+ nsStyledElement::UpdateEditableState();
}
nsresult
nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElementBase::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
+ if (HasFlag(NODE_HAS_NAME)) {
+ aDocument->
+ AddToNameTable(this, GetParsedAttr(nsGkAtoms::name)->GetAtomValue());
+ }
if (HasFlag(NODE_IS_EDITABLE) && GetContentEditableValue() == eTrue) {
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(aDocument);
if (htmlDocument) {
htmlDocument->ChangeContentEditableCount(this, +1);
}
}
}
@@ -943,17 +947,17 @@ nsGenericHTMLElement::UnbindFromTree(PRB
{
if (GetContentEditableValue() == eTrue) {
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(GetCurrentDoc());
if (htmlDocument) {
htmlDocument->ChangeContentEditableCount(this, -1);
}
}
- nsGenericElement::UnbindFromTree(aDeep, aNullParent);
+ nsStyledElement::UnbindFromTree(aDeep, aNullParent);
}
nsHTMLFormElement*
nsGenericHTMLElement::FindForm(nsHTMLFormElement* aCurrentForm)
{
// Make sure we don't end up finding a form that's anonymous from
// our point of view.
nsIContent* bindingParent = GetBindingParent();
@@ -1156,18 +1160,18 @@ nsGenericHTMLElement::SetAttr(PRInt32 aN
PRBool contentEditable = aNameSpaceID == kNameSpaceID_None &&
aName == nsGkAtoms::contenteditable;
PRInt32 change;
if (contentEditable) {
change = GetContentEditableValue() == eTrue ? -1 : 0;
SetFlags(NODE_MAY_HAVE_CONTENT_EDITABLE_ATTR);
}
- nsresult rv = nsGenericElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
- aNotify);
+ nsresult rv = nsStyledElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
+ aNotify);
NS_ENSURE_SUCCESS(rv, rv);
if (contentEditable) {
if (aValue.IsEmpty() || aValue.LowerCaseEqualsLiteral("true")) {
change += 1;
}
ChangeEditableState(change);
@@ -1180,17 +1184,22 @@ nsresult
nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{
PRBool contentEditable = PR_FALSE;
PRInt32 contentEditableChange;
// Check for event handlers
if (aNameSpaceID == kNameSpaceID_None) {
- if (aAttribute == nsGkAtoms::contenteditable) {
+ if (aAttribute == nsGkAtoms::name) {
+ // Have to do this before clearing flag. See RemoveFromNameTable
+ RemoveFromNameTable();
+ UnsetFlags(NODE_HAS_NAME);
+ }
+ else if (aAttribute == nsGkAtoms::contenteditable) {
contentEditable = PR_TRUE;
contentEditableChange = GetContentEditableValue() == eTrue ? -1 : 0;
}
else if (nsContentUtils::IsEventAttributeName(aAttribute,
EventNameType_HTML)) {
nsIEventListenerManager* manager = GetListenerManager(PR_FALSE);
if (manager) {
manager->RemoveScriptEventListener(aAttribute);
@@ -1217,36 +1226,57 @@ nsGenericHTMLElement::GetBaseTarget(nsAS
ownerDoc->GetBaseTarget(aBaseTarget);
} else {
aBaseTarget.Truncate();
}
}
//----------------------------------------------------------------------
+static PRBool
+CanHaveName(nsIAtom* aTag)
+{
+ return aTag == nsGkAtoms::img ||
+ aTag == nsGkAtoms::form ||
+ aTag == nsGkAtoms::applet ||
+ aTag == nsGkAtoms::embed ||
+ aTag == nsGkAtoms::object;
+}
PRBool
nsGenericHTMLElement::ParseAttribute(PRInt32 aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::dir) {
return aResult.ParseEnumValue(aValue, kDirTable, PR_FALSE);
}
if (aAttribute == nsGkAtoms::tabindex) {
return aResult.ParseIntWithBounds(aValue, -32768, 32767);
}
- if (aAttribute == nsGkAtoms::name && !aValue.IsEmpty()) {
+ if (aAttribute == nsGkAtoms::name) {
// Store name as an atom. name="" means that the element has no name,
// not that it has an emptystring as the name.
+ RemoveFromNameTable();
+ if (aValue.IsEmpty()) {
+ UnsetFlags(NODE_HAS_NAME);
+ return PR_FALSE;
+ }
+
aResult.ParseAtom(aValue);
+
+ if (CanHaveName(Tag())) {
+ SetFlags(NODE_HAS_NAME);
+ AddToNameTable(aResult.GetAtomValue());
+ }
+
return PR_TRUE;
}
if (aAttribute == nsGkAtoms::contenteditable) {
aResult.ParseAtom(aValue);
return PR_TRUE;
}
}
@@ -2496,16 +2526,18 @@ nsGenericHTMLFormElement::BindToTree(nsI
return NS_OK;
}
void
nsGenericHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
// Save state before doing anything
SaveState();
+
+ RemoveFromNameTable();
if (mForm) {
// Might need to unset mForm
if (aNullParent) {
// No more parent means no more form
ClearForm(PR_TRUE, PR_TRUE);
} else {
// Recheck whether we should still have an mForm.
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -494,22 +494,57 @@ public:
/**
* Locate an nsIEditor rooted at this content node, if there is one.
*/
NS_HIDDEN_(nsresult) GetEditor(nsIEditor** aEditor);
NS_HIDDEN_(nsresult) GetEditorInternal(nsIEditor** aEditor);
protected:
/**
+ * Add/remove this element to the documents name cache
+ */
+ void AddToNameTable(nsIAtom* aName) {
+ NS_ASSERTION(HasFlag(NODE_HAS_NAME), "Node lacking NODE_HAS_NAME flag");
+ nsIDocument* doc = GetCurrentDoc();
+ if (doc && !IsInAnonymousSubtree()) {
+ doc->AddToNameTable(this, aName);
+ }
+ }
+ void RemoveFromNameTable() {
+ if (HasFlag(NODE_HAS_NAME)) {
+ nsIDocument* doc = GetCurrentDoc();
+ if (doc) {
+ doc->RemoveFromNameTable(this, GetParsedAttr(nsGkAtoms::name)->
+ GetAtomValue());
+ }
+ }
+ }
+
+ /**
* Register or unregister an access key to this element based on the
* accesskey attribute.
- * @param aDoReg true to register, false to unregister
*/
+ void RegAccessKey()
+ {
+ if (HasFlag(NODE_HAS_ACCESSKEY)) {
+ RegUnRegAccessKey(PR_TRUE);
+ }
+ }
+
+ void UnregAccessKey()
+ {
+ if (HasFlag(NODE_HAS_ACCESSKEY)) {
+ RegUnRegAccessKey(PR_FALSE);
+ }
+ }
+
+private:
void RegUnRegAccessKey(PRBool aDoReg);
+protected:
/**
* Determine whether an attribute is an event (onclick, etc.)
* @param aName the attribute
* @return whether the name is an event handler name
*/
PRBool IsEventName(nsIAtom* aName);
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -203,17 +203,17 @@ nsHTMLAnchorElement::BindToTree(nsIDocum
Link::ResetLinkState(false);
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
- RegUnRegAccessKey(PR_TRUE);
+ RegAccessKey();
}
// Prefetch links
if (aDocument && nsHTMLDNSPrefetch::IsAllowed(GetOwnerDoc())) {
nsHTMLDNSPrefetch::PrefetchLow(this);
}
return rv;
}
@@ -221,17 +221,17 @@ nsHTMLAnchorElement::BindToTree(nsIDocum
void
nsHTMLAnchorElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
if (IsInDoc()) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
NS_IMETHODIMP
nsHTMLAnchorElement::Blur()
{
@@ -429,17 +429,17 @@ nsHTMLAnchorElement::GetHrefURI() const
}
nsresult
nsHTMLAnchorElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
bool reset = false;
if (aName == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
nsAutoString val;
GetHref(val);
if (!val.Equals(aValue)) {
reset = true;
@@ -455,29 +455,32 @@ nsHTMLAnchorElement::SetAttr(PRInt32 aNa
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (reset) {
Link::ResetLinkState(!!aNotify);
}
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID &&
!aValue.IsEmpty()) {
- RegUnRegAccessKey(PR_TRUE);
+ SetFlags(NODE_HAS_ACCESSKEY);
+ RegAccessKey();
}
return rv;
}
nsresult
nsHTMLAnchorElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{
if (aAttribute == nsGkAtoms::accesskey &&
kNameSpaceID_None == aNameSpaceID) {
- RegUnRegAccessKey(PR_FALSE);
+ // Have to unregister before clearing flag. See UnregAccessKey
+ UnregAccessKey();
+ UnsetFlags(NODE_HAS_ACCESSKEY);
}
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
aNotify);
// The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
// is important here! The attribute is not unset until UnsetAttr returns, and
// we will need the updated attribute value because notifying the document
--- a/content/html/content/src/nsHTMLAreaElement.cpp
+++ b/content/html/content/src/nsHTMLAreaElement.cpp
@@ -209,72 +209,75 @@ nsHTMLAreaElement::BindToTree(nsIDocumen
Link::ResetLinkState(false);
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
- RegUnRegAccessKey(PR_TRUE);
+ RegAccessKey();
}
return rv;
}
void
nsHTMLAreaElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false);
if (IsInDoc()) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
nsresult
nsHTMLAreaElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
if (aName == nsGkAtoms::accesskey && aNameSpaceID == kNameSpaceID_None) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsresult rv =
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue, aNotify);
// The ordering of the parent class's SetAttr call and Link::ResetLinkState
// is important here! The attribute is not set until SetAttr returns, and
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aName == nsGkAtoms::href && aNameSpaceID == kNameSpaceID_None) {
Link::ResetLinkState(!!aNotify);
}
if (aName == nsGkAtoms::accesskey && aNameSpaceID == kNameSpaceID_None &&
!aValue.IsEmpty()) {
- RegUnRegAccessKey(PR_TRUE);
+ SetFlags(NODE_HAS_ACCESSKEY);
+ RegAccessKey();
}
return rv;
}
nsresult
nsHTMLAreaElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{
if (aAttribute == nsGkAtoms::accesskey &&
aNameSpaceID == kNameSpaceID_None) {
- RegUnRegAccessKey(PR_FALSE);
+ // Have to unregister before clearing flag. See UnregAccessKey
+ UnregAccessKey();
+ UnsetFlags(NODE_HAS_ACCESSKEY);
}
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
aNotify);
// The ordering of the parent class's UnsetAttr call and Link::ResetLinkState
// is important here! The attribute is not unset until UnsetAttr returns, and
// we will need the updated attribute value because notifying the document
--- a/content/html/content/src/nsHTMLLabelElement.cpp
+++ b/content/html/content/src/nsHTMLLabelElement.cpp
@@ -203,27 +203,27 @@ nsHTMLLabelElement::BindToTree(nsIDocume
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
- RegUnRegAccessKey(PR_TRUE);
+ RegAccessKey();
}
return rv;
}
void
nsHTMLLabelElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
if (IsInDoc()) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
}
static PRBool
EventTargetIn(nsEvent *aEvent, nsIContent *aChild, nsIContent *aStop)
{
@@ -357,38 +357,41 @@ nsHTMLLabelElement::SubmitNamesValues(ns
return NS_OK;
}
nsresult
nsHTMLLabelElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPrefix,
const nsAString& aValue, PRBool aNotify)
{
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsresult rv =
nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix, aValue,
aNotify);
if (aName == nsGkAtoms::accesskey && kNameSpaceID_None == aNameSpaceID &&
!aValue.IsEmpty()) {
- RegUnRegAccessKey(PR_TRUE);
+ SetFlags(NODE_HAS_ACCESSKEY);
+ RegAccessKey();
}
return rv;
}
nsresult
nsHTMLLabelElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{
if (aAttribute == nsGkAtoms::accesskey &&
kNameSpaceID_None == aNameSpaceID) {
- RegUnRegAccessKey(PR_FALSE);
+ // Have to unregister before clearing flag. See UnregAccessKey
+ UnregAccessKey();
+ UnsetFlags(NODE_HAS_ACCESSKEY);
}
return nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
}
void
nsHTMLLabelElement::PerformAccesskey(PRBool aKeyCausesActivation,
PRBool aIsTrustedEvent)
@@ -428,19 +431,17 @@ nsHTMLLabelElement::GetControlContent()
// We have a @for. The id has to be linked to an element in the same document
// and this element should be a labelable form control.
nsIDocument* doc = GetCurrentDoc();
if (!doc) {
return nsnull;
}
- nsresult rv;
- nsIContent* content = doc->GetElementById(elementId, &rv);
- NS_ENSURE_SUCCESS(rv, nsnull);
+ nsIContent* content = doc->GetElementById(elementId);
if (!content) {
return nsnull;
}
nsCOMPtr<nsIFormControl> element = do_QueryInterface(content);
if (element && element->IsLabelableControl()) {
NS_ADDREF(content);
return content;
--- a/content/html/content/src/nsHTMLLegendElement.cpp
+++ b/content/html/content/src/nsHTMLLegendElement.cpp
@@ -214,36 +214,39 @@ nsHTMLLegendElement::GetAttributeChangeH
nsresult
nsHTMLLegendElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
nsIAtom* aPrefix, const nsAString& aValue,
PRBool aNotify)
{
PRBool accesskey = (aAttribute == nsGkAtoms::accesskey &&
aNameSpaceID == kNameSpaceID_None);
if (accesskey) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aAttribute,
aPrefix, aValue, aNotify);
if (accesskey && !aValue.IsEmpty()) {
- RegUnRegAccessKey(PR_TRUE);
+ SetFlags(NODE_HAS_ACCESSKEY);
+ RegAccessKey();
}
return rv;
}
nsresult
nsHTMLLegendElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
PRBool aNotify)
{
if (aAttribute == nsGkAtoms::accesskey &&
aNameSpaceID == kNameSpaceID_None) {
- RegUnRegAccessKey(PR_FALSE);
+ // Have to unregister before clearing flag. See UnregAccessKey
+ UnregAccessKey();
+ UnsetFlags(NODE_HAS_ACCESSKEY);
}
return nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
}
nsresult
nsHTMLLegendElement::Reset()
{
@@ -256,27 +259,27 @@ nsHTMLLegendElement::BindToTree(nsIDocum
PRBool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
- RegUnRegAccessKey(PR_TRUE);
+ RegAccessKey();
}
return rv;
}
void
nsHTMLLegendElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
{
if (IsInDoc()) {
- RegUnRegAccessKey(PR_FALSE);
+ UnregAccessKey();
}
nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent);
}
NS_IMETHODIMP
nsHTMLLegendElement::Focus()
{
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2630,36 +2630,28 @@ static void
FindNamedItems(nsIAtom* aName, nsIContent *aContent,
nsIdentifierMapEntry* aEntry)
{
NS_ASSERTION(aEntry->HasNameContentList(),
"Entry w/o content list passed to FindNamedItems()!");
NS_ASSERTION(!aEntry->IsInvalidName(),
"Entry that should never have a list passed to FindNamedItems()!");
- if (!aContent->IsElement()) {
- // non-elements are not named items nor can they have children.
- return;
- }
-
- Element* element = aContent->AsElement();
-
- if (aName == nsContentUtils::IsNamedItem(element)) {
- aEntry->AddNameElement(element);
+ if (aContent->HasFlag(NODE_HAS_NAME)) {
+ NS_ASSERTION(nsGenericHTMLElement::FromContent(aContent),
+ "Only HTML Elements should have a name");
+
+ nsGenericHTMLElement* elm = static_cast<nsGenericHTMLElement*>(aContent);
+ if (elm->GetParsedAttr(nsGkAtoms::name)->GetAtomValue() == aName) {
+ aEntry->AddNameElement(elm);
+ }
}
- if (!aEntry->GetIdElement() &&
- // Maybe this node has the right id?
- aName == element->GetID()) {
- aEntry->AddIdElement(element);
- }
-
- PRUint32 i, count = element->GetChildCount();
- for (i = 0; i < count; ++i) {
- FindNamedItems(aName, element->GetChildAt(i), aEntry);
+ for (nsINode::ChildIterator iter(aContent); !iter.IsDone(); iter.Next()) {
+ FindNamedItems(aName, iter, aEntry);
}
}
nsresult
nsHTMLDocument::ResolveName(const nsAString& aName,
nsIDOMHTMLFormElement *aForm,
nsISupports **aResult)
{
@@ -2672,37 +2664,17 @@ nsHTMLDocument::ResolveName(const nsAStr
nsIdentifierMapEntry *entry = mIdentifierMap.PutEntry(name);
NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
if (entry->IsInvalidName()) {
// There won't be any named items by this name -- it's reserved
return NS_OK;
}
- // Now we know we _might_ have items. Before looking at
- // entry->mNameContentList, make sure to flush out content (see
- // bug 69826).
- // This is a perf killer while the document is loading!
-
- // Make sure to stash away the current generation so we can check whether the
- // table changes when we flush.
- PRUint32 generation = mIdentifierMap.GetGeneration();
-
- // If we already have an entry->mNameContentList, we need to flush out
- // notifications too, so that it will get updated properly.
- FlushPendingNotifications(entry->HasNameContentList() ?
- Flush_ContentAndNotify : Flush_Content);
-
- if (generation != mIdentifierMap.GetGeneration()) {
- // Table changed, so the entry pointer is no longer valid; look up the
- // entry again, adding if necessary (the adding may be necessary in case
- // the flush actually deleted entries).
- entry = mIdentifierMap.PutEntry(name);
- NS_ENSURE_TRUE(entry, NS_ERROR_OUT_OF_MEMORY);
- }
+ // Now we know we _might_ have items.
if (!entry->HasNameContentList()) {
#ifdef DEBUG_jst
{
printf ("nsHTMLDocument name cache miss for name '%s'\n",
NS_ConvertUTF16toUTF8(aName).get());
}
#endif
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -235,20 +235,19 @@ public:
}
virtual nsresult SetEditingState(EditingState aState);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual NS_HIDDEN_(void) RemovedFromDocShell();
- virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId,
- nsresult *aResult)
+ virtual mozilla::dom::Element *GetElementById(const nsAString& aElementId)
{
- return nsDocument::GetElementById(aElementId, aResult);
+ return nsDocument::GetElementById(aElementId);
}
protected:
nsresult GetBodySize(PRInt32* aWidth,
PRInt32* aHeight);
nsresult PrePopulateIdentifierMap();
--- a/content/xbl/src/nsBindingManager.cpp
+++ b/content/xbl/src/nsBindingManager.cpp
@@ -616,27 +616,21 @@ nsBindingManager::SetWrappedJS(nsIConten
{
if (mDestroyed) {
return NS_OK;
}
return SetOrRemoveObject(mWrapperTable, aContent, aWrappedJS);
}
-nsresult
-nsBindingManager::ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument,
- nsIDocument* aNewDocument)
+void
+nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
+ nsIDocument* aOldDocument)
{
- // XXXbz this code is pretty broken, since moving from one document
- // to another always passes through a null document!
NS_PRECONDITION(aOldDocument != nsnull, "no old document");
- NS_PRECONDITION(!aNewDocument,
- "Changing to a non-null new document not supported yet");
- if (! aOldDocument)
- return NS_ERROR_NULL_POINTER;
// Hold a ref to the binding so it won't die when we remove it from our
// table.
nsRefPtr<nsXBLBinding> binding = GetBinding(aContent);
if (aContent->HasFlag(NODE_IS_INSERTION_PARENT)) {
nsRefPtr<nsXBLBinding> parentBinding = GetBinding(aContent->GetBindingParent());
if (parentBinding) {
parentBinding->RemoveInsertionParent(aContent);
@@ -645,28 +639,24 @@ nsBindingManager::ChangeDocumentFor(nsIC
if (!binding || !binding->HasInsertionParent(aContent)) {
RemoveInsertionParent(aContent);
aContent->UnsetFlags(NODE_IS_INSERTION_PARENT);
}
}
}
if (binding) {
- binding->ChangeDocument(aOldDocument, aNewDocument);
+ binding->ChangeDocument(aOldDocument, nsnull);
SetBinding(aContent, nsnull);
- if (aNewDocument)
- aNewDocument->BindingManager()->SetBinding(aContent, binding);
}
// Clear out insertion parents and content lists.
SetInsertionParent(aContent, nsnull);
SetContentListFor(aContent, nsnull);
SetAnonymousNodesFor(aContent, nsnull);
-
- return NS_OK;
}
nsIAtom*
nsBindingManager::ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID)
{
nsXBLBinding *binding = GetBinding(aContent);
if (binding) {
--- a/content/xbl/src/nsBindingManager.h
+++ b/content/xbl/src/nsBindingManager.h
@@ -79,31 +79,32 @@ public:
nsXBLBinding* GetBinding(nsIContent* aContent);
nsresult SetBinding(nsIContent* aContent, nsXBLBinding* aBinding);
nsIContent* GetInsertionParent(nsIContent* aContent);
nsresult SetInsertionParent(nsIContent* aContent, nsIContent* aResult);
/**
* Notify the binding manager that an element
- * has been moved from one document to another,
+ * has been removed from its document,
* so that it can update any bindings or
* nsIAnonymousContentCreator-created anonymous
* content that may depend on the document.
* @param aContent the element that's being moved
* @param aOldDocument the old document in which the
- * content resided. May be null if the the content
- * was not in any document.
- * @param aNewDocument the document in which the
- * content will reside. May be null if the content
- * will not reside in any document, or if the
- * content is being destroyed.
+ * content resided.
*/
- nsresult ChangeDocumentFor(nsIContent* aContent, nsIDocument* aOldDocument,
- nsIDocument* aNewDocument);
+ void RemovedFromDocument(nsIContent* aContent, nsIDocument* aOldDocument)
+ {
+ if (aContent->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR)) {
+ RemovedFromDocumentInternal(aContent, aOldDocument);
+ }
+ }
+ void RemovedFromDocumentInternal(nsIContent* aContent,
+ nsIDocument* aOldDocument);
nsIAtom* ResolveTag(nsIContent* aContent, PRInt32* aNameSpaceID);
/**
* Return a list of all explicit children, including any children
* that may have been inserted via XBL insertion points.
*/
nsresult GetContentListFor(nsIContent* aContent, nsIDOMNodeList** aResult);
--- a/content/xml/content/src/nsXMLElement.cpp
+++ b/content/xml/content/src/nsXMLElement.cpp
@@ -58,13 +58,118 @@ NS_INTERFACE_TABLE_HEAD(nsXMLElement)
NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsXMLElement)
NS_INTERFACE_TABLE_ENTRY(nsXMLElement, nsIDOMNode)
NS_INTERFACE_TABLE_ENTRY(nsXMLElement, nsIDOMElement)
NS_OFFSET_AND_INTERFACE_TABLE_END
NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Element)
NS_ELEMENT_INTERFACE_MAP_END
-
NS_IMPL_ADDREF_INHERITED(nsXMLElement, nsGenericElement)
NS_IMPL_RELEASE_INHERITED(nsXMLElement, nsGenericElement)
NS_IMPL_ELEMENT_CLONE(nsXMLElement)
+
+nsresult
+nsXMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+ PRBool aNotify)
+{
+ PRBool isId = PR_FALSE;
+ if (aAttribute == GetIDAttributeName() &&
+ aNameSpaceID == kNameSpaceID_None) {
+ // Have to do this before clearing flag. See RemoveFromIdTable
+ RemoveFromIdTable();
+ isId = PR_TRUE;
+ }
+
+ nsresult rv = nsGenericElement::UnsetAttr(aNameSpaceID, aAttribute, aNotify);
+
+ if (isId) {
+ UnsetFlags(NODE_HAS_ID);
+ }
+
+ return rv;
+}
+
+nsIAtom *
+nsXMLElement::GetIDAttributeName() const
+{
+ return mNodeInfo->GetIDAttributeAtom();
+}
+
+nsIAtom*
+nsXMLElement::DoGetID() const
+{
+ NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
+
+ nsIAtom* IDName = GetIDAttributeName();
+ if (IDName) {
+ const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(IDName);
+ if (attrVal) {
+ if (attrVal->Type() == nsAttrValue::eAtom) {
+ return attrVal->GetAtomValue();
+ }
+ if (attrVal->IsEmptyString()) {
+ return nsnull;
+ }
+ // Check if the ID has been stored as a string.
+ // This would occur if the ID attribute name changed after
+ // the ID was parsed.
+ if (attrVal->Type() == nsAttrValue::eString) {
+ nsAutoString idVal(attrVal->GetStringValue());
+
+ // Create an atom from the value and set it into the attribute list.
+ const_cast<nsAttrValue*>(attrVal)->ParseAtom(idVal);
+ return attrVal->GetAtomValue();
+ }
+ }
+ }
+ return nsnull;
+}
+
+PRBool
+nsXMLElement::ParseAttribute(PRInt32 aNamespaceID,
+ nsIAtom* aAttribute,
+ const nsAString& aValue,
+ nsAttrValue& aResult)
+{
+ if (aAttribute == GetIDAttributeName() &&
+ aNamespaceID == kNameSpaceID_None) {
+ // Store id as an atom. id="" means that the element has no id,
+ // not that it has an emptystring as the id.
+ RemoveFromIdTable();
+ if (aValue.IsEmpty()) {
+ UnsetFlags(NODE_HAS_ID);
+ return PR_FALSE;
+ }
+ aResult.ParseAtom(aValue);
+ SetFlags(NODE_HAS_ID);
+ AddToIdTable(aResult.GetAtomValue());
+ return PR_TRUE;
+ }
+
+ return PR_FALSE;
+}
+
+nsresult
+nsXMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+ nsIContent* aBindingParent,
+ PRBool aCompileEventHandlers)
+{
+ nsresult rv = nsGenericElement::BindToTree(aDocument, aParent,
+ aBindingParent,
+ aCompileEventHandlers);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aDocument && HasFlag(NODE_HAS_ID) && !GetBindingParent()) {
+ aDocument->AddToIdTable(this, DoGetID());
+ }
+
+ return NS_OK;
+}
+
+void
+nsXMLElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
+{
+ RemoveFromIdTable();
+
+ return nsGenericElement::UnbindFromTree(aDeep, aNullParent);
+}
--- a/content/xml/content/src/nsXMLElement.h
+++ b/content/xml/content/src/nsXMLElement.h
@@ -57,11 +57,25 @@ public:
// nsIDOMNode
NS_FORWARD_NSIDOMNODE(nsGenericElement::)
// nsIDOMElement
NS_FORWARD_NSIDOMELEMENT(nsGenericElement::)
// nsINode interface methods
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+
+ // nsIContent interface methods
+ virtual nsIAtom *GetIDAttributeName() const;
+ virtual nsIAtom* DoGetID() const;
+ virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
+ nsIContent* aBindingParent,
+ PRBool aCompileEventHandlers);
+ virtual void UnbindFromTree(PRBool aDeep, PRBool aNullParent);
+ virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
+ PRBool aNotify);
+ virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
+ nsIAtom* aAttribute,
+ const nsAString& aValue,
+ nsAttrValue& aResult);
};
#endif // nsXMLElement_h___
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -267,17 +267,17 @@ nsXULElement::Create(nsXULPrototypeEleme
PRBool aIsScriptable)
{
nsXULElement *element = new nsXULElement(aNodeInfo);
if (element) {
NS_ADDREF(element);
element->mPrototype = aPrototype;
if (aPrototype->mHasIdAttribute) {
- element->SetFlags(NODE_MAY_HAVE_ID);
+ element->SetFlags(NODE_HAS_ID);
}
if (aPrototype->mHasClassAttribute) {
element->SetFlags(NODE_MAY_HAVE_CLASS);
}
if (aPrototype->mHasStyleAttribute) {
element->SetFlags(NODE_MAY_HAVE_STYLE);
}
@@ -869,22 +869,19 @@ nsXULElement::MaybeAddPopupListener(nsIA
//
nsresult
nsXULElement::BindToTree(nsIDocument* aDocument,
nsIContent* aParent,
nsIContent* aBindingParent,
PRBool aCompileEventHandlers)
{
- // Calling the nsStyledElementBase method on purpose to skip over
- // nsStyledElement, since we don't want the style attribute
- // reparsing it does.
- nsresult rv = nsStyledElementBase::BindToTree(aDocument, aParent,
- aBindingParent,
- aCompileEventHandlers);
+ nsresult rv = nsStyledElement::BindToTree(aDocument, aParent,
+ aBindingParent,
+ aCompileEventHandlers);
NS_ENSURE_SUCCESS(rv, rv);
if (aDocument) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Missing a script blocker!");
// We're in a document now. Kick off the frame load.
LoadSrc();
}
@@ -1301,16 +1298,23 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpa
FindPrototypeAttribute(aNameSpaceID, aName);
if (protoattr) {
// We've got an attribute on the prototype, so we need to
// fully fault and remove the local copy.
rv = MakeHeavyweight();
NS_ENSURE_SUCCESS(rv, rv);
}
+ PRBool isId = PR_FALSE;
+ if (aName == nsGkAtoms::id && aNameSpaceID == kNameSpaceID_None) {
+ // Have to do this before clearing flag. See RemoveFromIdTable
+ RemoveFromIdTable();
+ isId = PR_TRUE;
+ }
+
PRInt32 index = mAttrsAndChildren.IndexOfAttr(aName, aNameSpaceID);
if (index < 0) {
NS_ASSERTION(!protoattr, "we used to have a protoattr, we should now "
"have a normal one");
return NS_OK;
}
@@ -1354,16 +1358,20 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpa
// the attribute from the attribute map even though the attribute is still
// on the element
// https://bugzilla.mozilla.org/show_bug.cgi?id=296205
// Deal with modification of magical attributes that side-effect
// other things.
// XXX Know how to remove POPUP event listeners when an attribute is unset?
+ if (isId) {
+ UnsetFlags(NODE_HAS_ID);
+ }
+
if (aNameSpaceID == kNameSpaceID_None) {
if (aName == nsGkAtoms::hidechrome &&
mNodeInfo->Equals(nsGkAtoms::window)) {
HideWindowChrome(PR_FALSE);
}
if (doc && doc->GetRootElement() == this) {
if ((aName == nsGkAtoms::activetitlebarcolor ||
@@ -1712,36 +1720,32 @@ nsXULElement::GetBuilder(nsIXULTemplateB
return NS_OK;
}
//----------------------------------------------------------------------
// Implementation methods
-/// XXX GetID must be defined here because we have proto attrs.
+// XXX DoGetID and DoGetClasses must be defined here because we have proto
+// attributes.
nsIAtom*
-nsXULElement::GetID() const
+nsXULElement::DoGetID() const
{
- if (!HasFlag(NODE_MAY_HAVE_ID)) {
- return nsnull;
- }
-
- const nsAttrValue* attrVal = FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::id);
-
- NS_ASSERTION(!attrVal ||
- attrVal->Type() == nsAttrValue::eAtom ||
- (attrVal->Type() == nsAttrValue::eString &&
- attrVal->GetStringValue().IsEmpty()),
- "unexpected attribute type");
-
- if (attrVal && attrVal->Type() == nsAttrValue::eAtom) {
- return attrVal->GetAtomValue();
- }
- return nsnull;
+ NS_ASSERTION(HasFlag(NODE_HAS_ID), "Unexpected call");
+ const nsAttrValue* attr =
+ FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::id);
+
+ // We need the nullcheck here because during unlink the prototype looses
+ // all of its attributes. We might want to change that.
+ // The nullcheck would also be needed if we make UnsetAttr use
+ // nsGenericElement::UnsetAttr as that calls out to various code between
+ // removing the attribute and clearing the NODE_HAS_ID flag.
+
+ return attr ? attr->GetAtomValue() : nsnull;
}
const nsAttrValue*
nsXULElement::DoGetClasses() const
{
NS_ASSERTION(HasFlag(NODE_MAY_HAVE_CLASS), "Unexpected call");
return FindLocalOrProtoAttr(kNameSpaceID_None, nsGkAtoms::_class);
}
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -523,17 +523,17 @@ public:
virtual void PerformAccesskey(PRBool aKeyCausesActivation,
PRBool aIsTrustedEvent);
nsresult ClickWithInputSource(PRUint16 aInputSource);
virtual nsIContent *GetBindingParent() const;
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull, PRBool aWithMouse = PR_FALSE);
- virtual nsIAtom* GetID() const;
+ virtual nsIAtom* DoGetID() const;
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual nsICSSStyleRule* GetInlineStyleRule();
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const;
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
--- a/content/xul/document/public/nsIXULDocument.h
+++ b/content/xul/document/public/nsIXULDocument.h
@@ -42,40 +42,32 @@
#include "nsString.h"
#include "nsCOMArray.h"
class nsIXULTemplateBuilder;
class nsIContent;
class nsIScriptGlobalObjectOwner;
-// {E486EA2A-5B37-4107-905F-EE062FB4FF97}
+// 3e872e97-b678-418e-a7e3-41b8305d4e75
#define NS_IXULDOCUMENT_IID \
-{ 0xe486ea2a, 0x5b37, 0x4107, \
- { 0x90, 0x5f, 0xee, 0x06, 0x2f, 0xb4, 0xff, 0x97 }}
+{ 0x3e872e97, 0xb678, 0x418e, \
+ { 0xa7, 0xe3, 0x41, 0xb8, 0x30, 0x5d, 0x4e, 0x75 } }
/*
* An XUL-specific extension to nsIDocument. Includes methods for
* setting the root resource of the document content model, a factory
* method for constructing the children of a node, etc.
*/
class nsIXULDocument : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IXULDOCUMENT_IID)
- // The resource-to-element map is a one-to-many mapping of RDF
- // resources to content elements.
-
- /**
- * Add an entry to the ID-to-element map.
- */
- NS_IMETHOD AddElementForID(nsIContent* aElement) = 0;
-
/**
* Get the elements for a particular resource --- all elements whose 'id'
* or 'ref' is aID. The nsCOMArray will be truncated and filled in with
* nsIContent pointers.
*/
NS_IMETHOD GetElementsForID(const nsAString& aID, nsCOMArray<nsIContent>& aElements) = 0;
/**
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -233,16 +233,17 @@ nsXULDocument::nsXULDocument(void)
// NOTE! nsDocument::operator new() zeroes out all members, so don't
// bother initializing members to 0.
// Override the default in nsDocument
mCharacterSet.AssignLiteral("UTF-8");
mDefaultElementType = kNameSpaceID_XUL;
+ mIsXUL = PR_TRUE;
mDelayFrameLoaderInitialization = PR_TRUE;
}
nsXULDocument::~nsXULDocument()
{
NS_ASSERTION(mNextSrcLoadWaiter == nsnull,
"unreferenced document still waiting for script source to load?");
@@ -975,35 +976,28 @@ nsXULDocument::AttributeWillChange(nsIDo
NS_PRECONDITION(aAttribute, "Must have an attribute that's changing!");
// XXXbz check aNameSpaceID, dammit!
// See if we need to update our ref map.
if (aAttribute == nsGkAtoms::ref ||
(aAttribute == nsGkAtoms::id && !aContent->GetIDAttributeName())) {
RemoveElementFromRefMap(aContent->AsElement());
}
-
- nsXMLDocument::AttributeWillChange(aDocument, aContent, aNameSpaceID,
- aAttribute, aModType);
}
void
nsXULDocument::AttributeChanged(nsIDocument* aDocument,
nsIContent* aElementContent, PRInt32 aNameSpaceID,
nsIAtom* aAttribute, PRInt32 aModType)
{
NS_ASSERTION(aDocument == this, "unexpected doc");
// XXXbz once we change AttributeChanged to take Element, we can nix this line
Element* aElement = aElementContent->AsElement();
- // Do this here so that all the exit paths below don't leave this undone
- nsXMLDocument::AttributeChanged(aDocument, aElement, aNameSpaceID,
- aAttribute, aModType);
-
// XXXbz check aNameSpaceID, dammit!
// See if we need to update our ref map.
if (aAttribute == nsGkAtoms::ref ||
(aAttribute == nsGkAtoms::id && !aElement->GetIDAttributeName())) {
AddElementToRefMap(aElement);
}
nsresult rv;
@@ -1095,66 +1089,46 @@ nsXULDocument::ContentAppended(nsIDocume
NS_ASSERTION(aDocument == this, "unexpected doc");
// Update our element map
nsresult rv = NS_OK;
for (nsIContent* cur = aFirstNewContent; cur && NS_SUCCEEDED(rv);
cur = cur->GetNextSibling()) {
rv = AddSubtreeToDocument(cur);
}
-
- nsXMLDocument::ContentAppended(aDocument, aContainer, aFirstNewContent,
- aNewIndexInContainer);
}
void
nsXULDocument::ContentInserted(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
NS_ASSERTION(aDocument == this, "unexpected doc");
AddSubtreeToDocument(aChild);
-
- nsXMLDocument::ContentInserted(aDocument, aContainer, aChild, aIndexInContainer);
}
void
nsXULDocument::ContentRemoved(nsIDocument* aDocument,
nsIContent* aContainer,
nsIContent* aChild,
PRInt32 aIndexInContainer)
{
NS_ASSERTION(aDocument == this, "unexpected doc");
RemoveSubtreeFromDocument(aChild);
-
- nsXMLDocument::ContentRemoved(aDocument, aContainer, aChild, aIndexInContainer);
}
//----------------------------------------------------------------------
//
// nsIXULDocument interface
//
NS_IMETHODIMP
-nsXULDocument::AddElementForID(nsIContent* aElement)
-{
- NS_PRECONDITION(aElement != nsnull, "null ptr");
- if (! aElement)
- return NS_ERROR_NULL_POINTER;
- if (!aElement->IsElement())
- return NS_ERROR_UNEXPECTED;
-
- UpdateIdTableEntry(aElement->AsElement());
- return NS_OK;
-}
-
-NS_IMETHODIMP
nsXULDocument::GetElementsForID(const nsAString& aID,
nsCOMArray<nsIContent>& aElements)
{
aElements.Clear();
nsCOMPtr<nsIAtom> atom = do_GetAtom(aID);
if (!atom)
return NS_ERROR_OUT_OF_MEMORY;
@@ -1656,27 +1630,25 @@ NS_IMETHODIMP
nsXULDocument::GetCommandDispatcher(nsIDOMXULCommandDispatcher** aTracker)
{
*aTracker = mCommandDispatcher;
NS_IF_ADDREF(*aTracker);
return NS_OK;
}
Element*
-nsXULDocument::GetElementById(const nsAString& aId, nsresult *aResult)
+nsXULDocument::GetElementById(const nsAString& aId)
{
nsCOMPtr<nsIAtom> atom(do_GetAtom(aId));
if (!atom) {
- *aResult = NS_ERROR_OUT_OF_MEMORY;
-
+ // This can only fail due OOM if the atom doesn't exist, in which
+ // case there couldn't possibly exist an entry for it.
return nsnull;
}
- *aResult = NS_OK;
-
if (!CheckGetElementByIdArg(atom))
return nsnull;
nsIdentifierMapEntry *entry = mIdentifierMap.GetEntry(atom);
if (entry) {
Element* element = entry->GetIdElement();
if (element)
return element;
@@ -1695,17 +1667,20 @@ nsXULDocument::AddElementToDocumentPre(E
{
// Do a bunch of work that's necessary when an element gets added
// to the XUL Document.
nsresult rv;
// 1. Add the element to the resource-to-element map. Also add it to
// the id map, since it seems this can be called when creating
// elements from prototypes.
- UpdateIdTableEntry(aElement);
+ nsIAtom* id = aElement->GetID();
+ if (id) {
+ AddToIdTable(aElement, id);
+ }
rv = AddElementToRefMap(aElement);
if (NS_FAILED(rv)) return rv;
// 2. If the element is a 'command updater' (i.e., has a
// "commandupdater='true'" attribute), then add the element to the
// document's command dispatcher
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::commandupdater,
nsGkAtoms::_true, eCaseMatters)) {
@@ -1830,17 +1805,20 @@ nsXULDocument::RemoveSubtreeFromDocument
if (NS_FAILED(rv))
return rv;
}
// 2. Remove the element from the resource-to-element map.
// Also remove it from the id map, since we added it in
// AddElementToDocumentPre().
RemoveElementFromRefMap(aElement);
- RemoveFromIdTable(aElement);
+ nsIAtom* id = aElement->GetID();
+ if (id) {
+ RemoveFromIdTable(aElement, id);
+ }
// 3. If the element is a 'command updater', then remove the
// element from the document's command dispatcher.
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::commandupdater,
nsGkAtoms::_true, eCaseMatters)) {
nsCOMPtr<nsIDOMElement> domelement = do_QueryInterface(aElement);
NS_ASSERTION(domelement != nsnull, "not a DOM element");
if (! domelement)
@@ -2467,18 +2445,16 @@ nsXULDocument::PrepareToWalk()
if (mState == eState_Master) {
// Add the root element
rv = CreateElementFromPrototype(proto, getter_AddRefs(root));
if (NS_FAILED(rv)) return rv;
rv = AppendChildTo(root, PR_FALSE);
if (NS_FAILED(rv)) return rv;
- // Add the root element to the XUL document's ID-to-element map.
- UpdateIdTableEntry(root);
rv = AddElementToRefMap(root);
if (NS_FAILED(rv)) return rv;
// Block onload until we've finished building the complete
// document content model.
BlockOnload();
}
--- a/content/xul/document/src/nsXULDocument.h
+++ b/content/xul/document/src/nsXULDocument.h
@@ -143,17 +143,16 @@ public:
// nsIMutationObserver interface
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTEWILLCHANGE
// nsIXULDocument interface
- NS_IMETHOD AddElementForID(nsIContent* aElement);
NS_IMETHOD GetElementsForID(const nsAString& aID,
nsCOMArray<nsIContent>& aElements);
NS_IMETHOD GetScriptGlobalObjectOwner(nsIScriptGlobalObjectOwner** aGlobalOwner);
NS_IMETHOD AddSubtreeToDocument(nsIContent* aContent);
NS_IMETHOD RemoveSubtreeFromDocument(nsIContent* aContent);
NS_IMETHOD SetTemplateBuilderFor(nsIContent* aContent,
nsIXULTemplateBuilder* aBuilder);
@@ -165,18 +164,17 @@ public:
// nsIDOMNode interface overrides
NS_IMETHOD CloneNode(PRBool deep, nsIDOMNode **_retval);
// nsDocument interface overrides
NS_IMETHOD GetElementById(const nsAString& aId, nsIDOMElement** aReturn)
{
return nsDocument::GetElementById(aId, aReturn);
}
- virtual mozilla::dom::Element* GetElementById(const nsAString & elementId,
- nsresult *aResult);
+ virtual mozilla::dom::Element* GetElementById(const nsAString & elementId);
// nsIDOMXULDocument interface
NS_DECL_NSIDOMXULDOCUMENT
// nsIDOMNSDocument
NS_IMETHOD GetContentType(nsAString& aContentType);
// nsICSSLoaderObserver
--- a/content/xul/templates/src/nsXULContentBuilder.cpp
+++ b/content/xul/templates/src/nsXULContentBuilder.cpp
@@ -629,27 +629,16 @@ nsXULContentBuilder::BuildContentFromTem
rv = aChild->GetId(id);
if (NS_FAILED(rv))
return rv;
rv = realKid->SetAttr(kNameSpaceID_None, nsGkAtoms::id, id, PR_FALSE);
if (NS_FAILED(rv))
return rv;
- if (! aNotify) {
- // XUL document will watch us, and take care of making
- // sure that we get added to or removed from the
- // element map if aNotify is true. If not, we gotta do
- // it ourselves. Yay.
- nsCOMPtr<nsIXULDocument> xuldoc =
- do_QueryInterface(mRoot->GetDocument());
- if (xuldoc)
- xuldoc->AddElementForID(realKid);
- }
-
// Set up the element's 'container' and 'empty' attributes.
SetContainerAttrs(realKid, aChild, PR_TRUE, PR_FALSE);
}
else if (tag == nsGkAtoms::textnode &&
nameSpaceID == kNameSpaceID_XUL) {
// <xul:text value="..."> is replaced by text of the
// actual value of the 'rdf:resource' attribute for the
// given node.
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -3040,17 +3040,18 @@ static JSPropertySpec OptionsProperties[
{0}
};
static JSBool
GetOptionsProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
if (JSVAL_IS_INT(id)) {
uint32 optbit = (uint32) JSVAL_TO_INT(id);
- if ((optbit & (optbit - 1)) == 0 && optbit <= JSOPTION_WERROR)
+ if (((optbit & (optbit - 1)) == 0 && optbit <= JSOPTION_WERROR) ||
+ optbit == JSOPTION_RELIMIT)
*vp = (JS_GetOptions(cx) & optbit) ? JSVAL_TRUE : JSVAL_FALSE;
}
return JS_TRUE;
}
static JSBool
SetOptionsProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
--- a/editor/composer/src/nsEditorSpellCheck.cpp
+++ b/editor/composer/src/nsEditorSpellCheck.cpp
@@ -55,18 +55,28 @@
#include "nsISupportsPrimitives.h"
#include "nsServiceManagerUtils.h"
#include "nsIChromeRegistry.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsITextServicesFilter.h"
#include "mozilla/Services.h"
-NS_IMPL_ISUPPORTS1(nsEditorSpellCheck,
- nsIEditorSpellCheck)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsEditorSpellCheck)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsEditorSpellCheck)
+
+NS_INTERFACE_MAP_BEGIN(nsEditorSpellCheck)
+ NS_INTERFACE_MAP_ENTRY(nsIEditorSpellCheck)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditorSpellCheck)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsEditorSpellCheck)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_2(nsEditorSpellCheck,
+ mSpellChecker,
+ mTxtSrvFilter)
nsEditorSpellCheck::nsEditorSpellCheck()
: mSuggestedWordIndex(0)
, mDictionaryIndex(0)
{
}
nsEditorSpellCheck::~nsEditorSpellCheck()
--- a/editor/composer/src/nsEditorSpellCheck.h
+++ b/editor/composer/src/nsEditorSpellCheck.h
@@ -39,30 +39,32 @@
#ifndef nsEditorSpellCheck_h___
#define nsEditorSpellCheck_h___
#include "nsIEditorSpellCheck.h"
#include "nsISpellChecker.h"
#include "nsCOMPtr.h"
+#include "nsCycleCollectionParticipant.h"
#define NS_EDITORSPELLCHECK_CID \
{ /* {75656ad9-bd13-4c5d-939a-ec6351eea0cc} */ \
0x75656ad9, 0xbd13, 0x4c5d, \
{ 0x93, 0x9a, 0xec, 0x63, 0x51, 0xee, 0xa0, 0xcc }\
}
class nsEditorSpellCheck : public nsIEditorSpellCheck
{
public:
nsEditorSpellCheck();
virtual ~nsEditorSpellCheck();
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsEditorSpellCheck)
/* Declare all methods in the nsIEditorSpellCheck interface */
NS_DECL_NSIEDITORSPELLCHECK
protected:
nsCOMPtr<nsISpellChecker> mSpellChecker;
nsTArray<nsString> mSuggestedWordList;
--- a/editor/txtsvc/src/nsFilteredContentIterator.cpp
+++ b/editor/txtsvc/src/nsFilteredContentIterator.cpp
@@ -60,17 +60,31 @@ nsFilteredContentIterator::nsFilteredCon
}
//------------------------------------------------------------
nsFilteredContentIterator::~nsFilteredContentIterator()
{
}
//------------------------------------------------------------
-NS_IMPL_ISUPPORTS1(nsFilteredContentIterator, nsIContentIterator)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFilteredContentIterator)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFilteredContentIterator)
+
+NS_INTERFACE_MAP_BEGIN(nsFilteredContentIterator)
+ NS_INTERFACE_MAP_ENTRY(nsIContentIterator)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentIterator)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsFilteredContentIterator)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_5(nsFilteredContentIterator,
+ mCurrentIterator,
+ mIterator,
+ mPreIterator,
+ mFilter,
+ mRange)
//------------------------------------------------------------
nsresult
nsFilteredContentIterator::Init(nsINode* aRoot)
{
NS_ENSURE_TRUE(mPreIterator, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(mIterator, NS_ERROR_FAILURE);
mIsOutOfRange = PR_FALSE;
--- a/editor/txtsvc/src/nsFilteredContentIterator.h
+++ b/editor/txtsvc/src/nsFilteredContentIterator.h
@@ -39,26 +39,28 @@
#define nsFilteredContentIterator_h__
#include "nsIContentIterator.h"
#include "nsCOMPtr.h"
#include "nsIAtom.h"
#include "nsITextServicesFilter.h"
#include "nsIDOMNSRange.h"
#include "nsIRangeUtils.h"
+#include "nsCycleCollectionParticipant.h"
/**
*
*/
class nsFilteredContentIterator : public nsIContentIterator
{
public:
// nsISupports interface...
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsFilteredContentIterator)
nsFilteredContentIterator(nsITextServicesFilter* aFilter);
virtual ~nsFilteredContentIterator();
/* nsIContentIterator */
virtual nsresult Init(nsINode* aRoot);
virtual nsresult Init(nsIDOMRange* aRange);
--- a/editor/txtsvc/src/nsTextServicesDocument.cpp
+++ b/editor/txtsvc/src/nsTextServicesDocument.cpp
@@ -142,43 +142,34 @@ nsTextServicesDocument::RegisterAtoms()
/* static */
void
nsTextServicesDocument::Shutdown()
{
NS_IF_RELEASE(sRangeHelper);
}
-#define DEBUG_TEXT_SERVICES__DOCUMENT_REFCNT 1
-
-#ifdef DEBUG_TEXT_SERVICES__DOCUMENT_REFCNT
-
-nsrefcnt nsTextServicesDocument::AddRef(void)
-{
- return ++mRefCnt;
-}
-
-nsrefcnt nsTextServicesDocument::Release(void)
-{
- NS_PRECONDITION(0 != mRefCnt, "dup release");
- if (--mRefCnt == 0) {
- NS_DELETEXPCOM(this);
- return 0;
- }
- return mRefCnt;
-}
-
-#else
-
-NS_IMPL_ADDREF(nsTextServicesDocument)
-NS_IMPL_RELEASE(nsTextServicesDocument)
-
-#endif
-
-NS_IMPL_QUERY_INTERFACE1(nsTextServicesDocument, nsITextServicesDocument)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTextServicesDocument)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTextServicesDocument)
+
+NS_INTERFACE_MAP_BEGIN(nsTextServicesDocument)
+ NS_INTERFACE_MAP_ENTRY(nsITextServicesDocument)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsITextServicesDocument)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsTextServicesDocument)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_8(nsTextServicesDocument,
+ mDOMDocument,
+ mSelCon,
+ mIterator,
+ mPrevTextBlock,
+ mNextTextBlock,
+ mNotifier,
+ mExtent,
+ mTxtSvcFilter)
NS_IMETHODIMP
nsTextServicesDocument::InitWithEditor(nsIEditor *aEditor)
{
nsresult result = NS_OK;
nsCOMPtr<nsISelectionController> selCon;
nsCOMPtr<nsIDOMDocument> doc;
--- a/editor/txtsvc/src/nsTextServicesDocument.h
+++ b/editor/txtsvc/src/nsTextServicesDocument.h
@@ -46,16 +46,17 @@
#include "nsIEditor.h"
#include "nsIEditActionListener.h"
#include "nsITextServicesDocument.h"
#include "nsTArray.h"
#include "nsTSDNotifier.h"
#include "nsISelectionController.h"
#include "nsITextServicesFilter.h"
#include "nsWeakReference.h"
+#include "nsCycleCollectionParticipant.h"
class nsIRangeUtils;
class OffsetEntry;
/** implementation of a text services object.
*
*/
class nsTextServicesDocument : public nsITextServicesDocument
@@ -130,17 +131,18 @@ public:
*/
static void RegisterAtoms();
/** To be called at module shutdown
*/
static void Shutdown();
/* Macro for AddRef(), Release(), and QueryInterface() */
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(nsTextServicesDocument)
/* nsITextServicesDocument method implementations. */
NS_IMETHOD InitWithEditor(nsIEditor *aEditor);
NS_IMETHOD GetDocument(nsIDOMDocument **aDoc);
NS_IMETHOD SetExtent(nsIDOMRange* aDOMRange);
NS_IMETHOD ExpandRangeToWordBoundaries(nsIDOMRange *aRange);
NS_IMETHOD SetFilter(nsITextServicesFilter *aFilter);
NS_IMETHOD GetCurrentTextBlock(nsString *aStr);
--- a/embedding/Makefile.in
+++ b/embedding/Makefile.in
@@ -47,9 +47,13 @@ MODULE = embed
DIRS = base components browser
ifdef ENABLE_TESTS
XPCSHELL_TESTS = tests/unit
DIRS += test
endif
+ifeq ($(OS_TARGET),Android)
+TOOL_DIRS = android
+endif
+
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/embedding/android/AndroidManifest.xml.in
@@ -0,0 +1,66 @@
+#filter substitution
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.mozilla.@MOZ_APP_NAME@"
+ android:versionCode="1"
+ android:versionName="1.9.3"
+ android:sharedUserId="org.mozilla.sharedID">
+ <uses-sdk android:minSdkVersion="5"
+ android:targetSdkVersion="5"/>
+
+ <uses-permission android:name="android.permission.INTERNET"/>
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+ <application android:label="@MOZ_APP_DISPLAYNAME@"
+ android:icon="@drawable/icon">
+ <activity android:name="App"
+ android:label="@MOZ_APP_DISPLAYNAME@"
+ android:configChanges="keyboard|keyboardHidden|orientation|mcc|mnc"
+ android:windowSoftInputMode="stateUnspecified|adjustResize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ <!-- Default browser intents -->
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ <data android:scheme="about" />
+ <data android:scheme="javascript" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ <data android:mimeType="text/html"/>
+ <data android:mimeType="text/plain"/>
+ <data android:mimeType="application/xhtml+xml"/>
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.intent.action.WEB_SEARCH" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:scheme="" />
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ </intent-filter>
+
+ <!-- For debugging -->
+ <intent-filter>
+ <action android:name="org.mozilla.gecko.DEBUG" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ <receiver android:enabled="true" android:name="Restarter">
+ <intent-filter>
+ <action android:name="org.mozilla.gecko.restart@MOZ_APP_NAME@" />
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
new file mode 100644
--- /dev/null
+++ b/embedding/android/App.java.in
@@ -0,0 +1,48 @@
+/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Brad Lassey <blassey@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 ***** */
+
+#filter substitution
+package org.mozilla.@MOZ_APP_NAME@;
+
+import org.mozilla.gecko.GeckoApp;
+
+public class App extends GeckoApp {
+ public String getAppName() {
+ return "@MOZ_APP_NAME@";
+ }
+};
+
new file mode 100644
--- /dev/null
+++ b/embedding/android/GeckoApp.java
@@ -0,0 +1,372 @@
+/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009-2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir@pobox.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 ***** */
+
+package org.mozilla.gecko;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+import java.nio.*;
+
+import android.os.*;
+import android.app.*;
+import android.text.*;
+import android.view.*;
+import android.view.inputmethod.*;
+import android.content.*;
+import android.graphics.*;
+import android.widget.*;
+import android.hardware.*;
+
+import android.util.*;
+
+abstract public class GeckoApp
+ extends Activity
+{
+ public static FrameLayout mainLayout;
+ public static GeckoSurfaceView surfaceView;
+ public static GeckoApp mAppContext;
+
+ public static boolean useSoftwareDrawing;
+
+ void launch()
+ {
+ // unpack files in the components directory
+ unpackComponents();
+ // and then fire us up
+ Intent i = getIntent();
+ String env = i.getStringExtra("env0");
+ Log.i("GeckoApp", "env0: "+ env);
+ for (int c = 1; env != null; c++) {
+ GeckoAppShell.putenv(env);
+ env = i.getStringExtra("env" + c);
+ Log.i("GeckoApp", "env"+ c +": "+ env);
+ }
+ GeckoAppShell.runGecko(getApplication().getPackageResourcePath(),
+ i.getStringExtra("args"),
+ i.getDataString());
+ }
+
+ /** Called when the activity is first created. */
+ @Override
+ public void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+
+ mAppContext = this;
+
+ // hide our window's title, we don't want it
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ surfaceView = new GeckoSurfaceView(this);
+
+ mainLayout = new FrameLayout(this);
+ mainLayout.addView(surfaceView,
+ new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
+ FrameLayout.LayoutParams.FILL_PARENT));
+
+ boolean useLaunchButton = false;
+
+ String intentAction = getIntent().getAction();
+ if (intentAction != null && intentAction.equals("org.mozilla.gecko.DEBUG"))
+ useLaunchButton = true;
+
+ setContentView(mainLayout,
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ useSoftwareDrawing = true; //isInEmulator() == 1;
+
+ if (!GeckoAppShell.sGeckoRunning) {
+ // Load our JNI libs; we need to do this before launch() because
+ // setInitialSize will be called even before Gecko is actually up
+ // and running.
+ GeckoAppShell.loadGeckoLibs();
+
+ if (useLaunchButton) {
+ final Button b = new Button(this);
+ b.setText("Launch");
+ b.setOnClickListener(new Button.OnClickListener() {
+ public void onClick (View v) {
+ // hide the button so we can't be launched again
+ mainLayout.removeView(b);
+ launch();
+ }
+ });
+ mainLayout.addView(b, 300, 200);
+ } else {
+ launch();
+ }
+ }
+
+ super.onCreate(savedInstanceState);
+ }
+
+ @Override
+ public void onPause()
+ {
+ // The user is navigating away from this activity, but nothing
+ // has come to the foreground yet; for Gecko, we may want to
+ // stop repainting, for example.
+
+ // Whatever we do here should be fast, because we're blocking
+ // the next activity from showing up until we finish.
+
+ // onPause will be followed by either onResume or onStop.
+ super.onPause();
+ }
+
+ @Override
+ public void onResume()
+ {
+ // After an onPause, the activity is back in the foreground.
+ // Undo whatever we did in onPause.
+ super.onResume();
+ }
+
+ @Override
+ public void onStop()
+ {
+ // We're about to be stopped, potentially in preparation for
+ // being destroyed. We're killable after this point -- as I
+ // understand it, in extreme cases the process can be terminated
+ // without going through onDestroy.
+ //
+ // We might also get an onRestart after this; not sure what
+ // that would mean for Gecko if we were to kill it here.
+ // Instead, what we should do here is save prefs, session,
+ // etc., and generally mark the profile as 'clean', and then
+ // dirty it again if we get an onResume.
+
+ // XXX do the above.
+
+ super.onStop();
+ }
+
+ @Override
+ public void onDestroy()
+ {
+ // Tell Gecko to shutting down; we'll end up calling System.exit()
+ // in onXreExit.
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_STOPPING));
+
+ super.onDestroy();
+ }
+
+ @Override
+ public void onConfigurationChanged(android.content.res.Configuration newConfig)
+ {
+ // nothing, just ignore
+ super.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ public void onLowMemory()
+ {
+ // XXX TODO
+ super.onLowMemory();
+ }
+
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_VOLUME_UP:
+ case KeyEvent.KEYCODE_VOLUME_DOWN:
+ return false;
+ default:
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
+ return true;
+ }
+ }
+
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
+ return true;
+ }
+
+ public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
+ return true;
+ }
+
+ abstract public String getAppName();
+
+ protected void unpackComponents()
+ {
+ ZipFile zip;
+ InputStream listStream;
+
+ try {
+ File componentsDir = new File("/data/data/org.mozilla." + getAppName() +"/components");
+ componentsDir.mkdir();
+ zip = new ZipFile(getApplication().getPackageResourcePath());
+
+ ZipEntry componentsList = zip.getEntry("components/components.list");
+ if (componentsList == null) {
+ Log.i("GeckoAppJava", "Can't find components.list !");
+ return;
+ }
+
+ listStream = new BufferedInputStream(zip.getInputStream(componentsList));
+ } catch (Exception e) {
+ Log.i("GeckoAppJava", e.toString());
+ return;
+ }
+
+ byte[] buf = new byte[8192];
+
+ StreamTokenizer tkn = new StreamTokenizer(new InputStreamReader(listStream));
+ String line = "components/";
+ int status;
+ tkn.eolIsSignificant(true);
+ do {
+ try {
+ status = tkn.nextToken();
+ } catch (IOException e) {
+ Log.i("GeckoAppJava", e.toString());
+ return;
+ }
+ switch (status) {
+ case StreamTokenizer.TT_WORD:
+ line += tkn.sval;
+ break;
+ case StreamTokenizer.TT_NUMBER:
+ line += tkn.nval;
+ break;
+ case StreamTokenizer.TT_EOF:
+ case StreamTokenizer.TT_EOL:
+ if (!line.endsWith(".js"))
+ unpackFile(zip, buf, null, line);
+ line = "components/";
+ break;
+ }
+ } while (status != StreamTokenizer.TT_EOF);
+
+ unpackFile(zip, buf, null, "application.ini");
+ }
+
+ private void unpackFile(ZipFile zip, byte[] buf, ZipEntry fileEntry, String name)
+ {
+ if (fileEntry == null)
+ fileEntry = zip.getEntry(name);
+ if (fileEntry == null) {
+ Log.i("GeckoAppJava", "Can't find " + name + " in " + zip.getName());
+ return;
+ }
+
+ File outFile = new File("/data/data/org.mozilla." + getAppName() + "/" + name);
+ if (outFile.exists() &&
+ outFile.lastModified() >= fileEntry.getTime() &&
+ outFile.length() == fileEntry.getSize())
+ return;
+
+ try {
+ File dir = outFile.getParentFile();
+ if (!outFile.exists())
+ dir.mkdirs();
+ } catch (Exception e) {
+ Log.i("GeckoAppJava", e.toString());
+ return;
+ }
+
+ InputStream fileStream;
+ try {
+ fileStream = zip.getInputStream(fileEntry);
+ } catch (Exception e) {
+ Log.i("GeckoAppJava", e.toString());
+ return;
+ }
+
+ OutputStream outStream;
+ try {
+ outStream = new FileOutputStream(outFile);
+
+ while (fileStream.available() > 0) {
+ int read = fileStream.read(buf, 0, buf.length);
+ outStream.write(buf, 0, read);
+ }
+
+ fileStream.close();
+ outStream.close();
+ } catch (Exception e) {
+ Log.i("GeckoAppJava", e.toString());
+ return;
+ }
+ }
+
+ public String getEnvString() {
+ Map<String,String> envMap = System.getenv();
+ Set<Map.Entry<String,String>> envSet = envMap.entrySet();
+ Iterator<Map.Entry<String,String>> envIter = envSet.iterator();
+ StringBuffer envstr = new StringBuffer();
+ int c = 0;
+ while (envIter.hasNext()) {
+ Map.Entry<String,String> entry = envIter.next();
+ // No need to pass env vars that we know the system provides
+ // Unnecessary vars need to be trimmed since amount of data
+ // we can pass this way is limited
+ if (!entry.getKey().equals("BOOTCLASSPATH") &&
+ !entry.getKey().equals("ANDROID_SOCKET_zygote") &&
+ !entry.getKey().equals("TMPDIR") &&
+ !entry.getKey().equals("ANDROID_BOOTLOGO") &&
+ !entry.getKey().equals("EXTERNAL_STORAGE") &&
+ !entry.getKey().equals("ANDROID_ASSETS") &&
+ !entry.getKey().equals("PATH") &&
+ !entry.getKey().equals("TERMINFO") &&
+ !entry.getKey().equals("LD_LIBRARY_PATH") &&
+ !entry.getKey().equals("ANDROID_DATA") &&
+ !entry.getKey().equals("ANDROID_PROPERTY_WORKSPACE") &&
+ !entry.getKey().equals("ANDROID_ROOT")) {
+ envstr.append(" --es env" + c + " " + entry.getKey() + "="
+ + entry.getValue());
+ c++;
+ }
+ }
+ return envstr.toString();
+ }
+
+ public void doRestart() {
+ try {
+ String action = "org.mozilla.gecko.restart" + getAppName();
+ String amCmd = "/system/bin/am broadcast -a " + action + getEnvString() + " -n org.mozilla." + getAppName() + "/org.mozilla." + getAppName() + ".Restarter";
+ Log.i("GeckoAppJava", amCmd);
+ Runtime.getRuntime().exec(amCmd);
+ } catch (Exception e) {
+ Log.i("GeckoAppJava", e.toString());
+ }
+ System.exit(0);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/embedding/android/GeckoAppShell.java
@@ -0,0 +1,219 @@
+/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir@pobox.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 ***** */
+
+package org.mozilla.gecko;
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+import java.nio.*;
+
+import android.os.*;
+import android.app.*;
+import android.text.*;
+import android.view.*;
+import android.view.inputmethod.*;
+import android.content.*;
+import android.graphics.*;
+import android.widget.*;
+import android.hardware.*;
+
+import android.util.*;
+import android.content.DialogInterface;
+
+class GeckoAppShell
+{
+ static {
+ sGeckoRunning = false;
+ }
+
+ // static members only
+ private GeckoAppShell() { }
+
+ static boolean sGeckoRunning;
+
+ static private boolean gRestartScheduled = false;
+
+ /* The Android-side API: API methods that Android calls */
+
+ // Initialization methods
+ public static native void nativeInit();
+ public static native void nativeRun(String args);
+
+ // helper methods
+ public static native void setInitialSize(int width, int height);
+ public static native void setSurfaceView(GeckoSurfaceView sv);
+ public static native void putenv(String map);
+
+ // java-side stuff
+ public static void loadGeckoLibs() {
+ // The package data lib directory isn't placed in ld.so's
+ // search path, so we have to manually load libraries that
+ // libxul will depend on. Not ideal.
+
+ // MozAlloc
+ System.loadLibrary("mozalloc");
+
+ // NSPR
+ System.loadLibrary("nspr4");
+ System.loadLibrary("plc4");
+ System.loadLibrary("plds4");
+
+ // SQLite
+ System.loadLibrary("mozsqlite3");
+
+ // NSS
+ System.loadLibrary("nssutil3");
+ System.loadLibrary("nss3");
+ System.loadLibrary("ssl3");
+ System.loadLibrary("smime3");
+
+ // JS
+ System.loadLibrary("mozjs");
+
+ // XUL
+ System.loadLibrary("xul");
+
+ // xpcom glue -- needed to load binary components
+ System.loadLibrary("xpcom");
+
+ // Root certs. someday we may teach security/manager/ssl/src/nsNSSComponent.cpp to find ckbi itself
+ System.loadLibrary("nssckbi");
+ }
+
+ public static void runGecko(String apkPath, String args, String url) {
+ // run gecko -- it will spawn its own thread
+ GeckoAppShell.nativeInit();
+
+ // Tell Gecko where the target surface view is for rendering
+ GeckoAppShell.setSurfaceView(GeckoApp.surfaceView);
+
+ sGeckoRunning = true;
+
+ // First argument is the .apk path
+ String combinedArgs = apkPath;
+ if (args != null)
+ combinedArgs += " " + args;
+ if (url != null)
+ combinedArgs += " " + url;
+ // and go
+ GeckoAppShell.nativeRun(combinedArgs);
+ }
+
+ private static GeckoEvent mLastDrawEvent;
+
+ public static void sendEventToGecko(GeckoEvent e) {
+ if (sGeckoRunning)
+ notifyGeckoOfEvent(e);
+ }
+
+ // Tell the Gecko event loop that an event is available.
+ public static native void notifyGeckoOfEvent(GeckoEvent event);
+
+ /*
+ * The Gecko-side API: API methods that Gecko calls
+ */
+ public static void scheduleRedraw() {
+ // Redraw everything
+ scheduleRedraw(0, -1, -1, -1, -1);
+ }
+
+ public static void scheduleRedraw(int nativeWindow, int x, int y, int w, int h) {
+ GeckoEvent e;
+
+ if (x == -1) {
+ e = new GeckoEvent(GeckoEvent.DRAW, null);
+ } else {
+ e = new GeckoEvent(GeckoEvent.DRAW, new Rect(x, y, w, h));
+ }
+
+ e.mNativeWindow = nativeWindow;
+
+ sendEventToGecko(e);
+ }
+
+ public static void showIME(int state) {
+ InputMethodManager imm = (InputMethodManager)
+ GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ GeckoApp.surfaceView.mIMEState = state;
+ if (state != 0)
+ imm.showSoftInput(GeckoApp.surfaceView, 0);
+ else
+ imm.hideSoftInputFromWindow(GeckoApp.surfaceView.getWindowToken(), 0);
+ }
+
+ public static void enableAccelerometer(boolean enable) {
+ SensorManager sm = (SensorManager)
+ GeckoApp.surfaceView.getContext().getSystemService(Context.SENSOR_SERVICE);
+
+ if (enable) {
+ Sensor accelSensor = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+ if (accelSensor == null)
+ return;
+
+ sm.registerListener(GeckoApp.surfaceView, accelSensor, SensorManager.SENSOR_DELAY_GAME);
+ } else {
+ sm.unregisterListener(GeckoApp.surfaceView);
+ }
+ }
+
+ public static void returnIMEQueryResult(String result, int selectionStart, int selectionEnd) {
+ GeckoApp.surfaceView.inputConnection.mSelectionStart = selectionStart;
+ GeckoApp.surfaceView.inputConnection.mSelectionEnd = selectionEnd;
+ try {
+ GeckoApp.surfaceView.inputConnection.mQueryResult.put(result);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ static void onXreExit() {
+ sGeckoRunning = false;
+ Log.i("GeckoAppJava", "XRE exited");
+ if (gRestartScheduled) {
+ GeckoApp.mAppContext.doRestart();
+ } else {
+ Log.i("GeckoAppJava", "we're done, good bye");
+ System.exit(0);
+ }
+
+ }
+ static void scheduleRestart() {
+ Log.i("GeckoAppJava", "scheduling restart");
+ gRestartScheduled = true;
+ }
+}
new file mode 100644
--- /dev/null
+++ b/embedding/android/GeckoEvent.java
@@ -0,0 +1,165 @@
+/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2009-2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir@pobox.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 ***** */
+
+package org.mozilla.gecko;
+
+import android.os.*;
+import android.app.*;
+import android.view.*;
+import android.content.*;
+import android.graphics.*;
+import android.widget.*;
+import android.hardware.*;
+
+import android.util.Log;
+
+/* We're not allowed to hold on to most events given to us
+ * so we save the parts of the events we want to use in GeckoEvent.
+ * Fields have different meanings depending on the event type.
+ */
+
+public class GeckoEvent {
+ public static final int INVALID = -1;
+ public static final int NATIVE_POKE = 0;
+ public static final int KEY_EVENT = 1;
+ public static final int MOTION_EVENT = 2;
+ public static final int SENSOR_EVENT = 3;
+ public static final int IME_EVENT = 4;
+ public static final int DRAW = 5;
+ public static final int SIZE_CHANGED = 6;
+ public static final int ACTIVITY_STOPPING = 7;
+
+ public static final int IME_BATCH_END = 0;
+ public static final int IME_BATCH_BEGIN = 1;
+ public static final int IME_SET_TEXT = 2;
+ public static final int IME_GET_TEXT = 3;
+ public static final int IME_DELETE_TEXT = 4;
+
+ public int mType;
+ public int mAction;
+ public long mTime;
+ public Point mP0, mP1;
+ public Rect mRect;
+ public float mX, mY, mZ;
+
+ public int mMetaState, mFlags;
+ public int mKeyCode, mUnicodeChar;
+ public int mCount, mCount2;
+ public String mCharacters;
+
+ public int mNativeWindow;
+
+ public GeckoEvent() {
+ mType = NATIVE_POKE;
+ }
+
+ public GeckoEvent(int evType) {
+ mType = evType;
+ }
+
+ public GeckoEvent(KeyEvent k) {
+ mType = KEY_EVENT;
+ mAction = k.getAction();
+ mTime = k.getEventTime();
+ mMetaState = k.getMetaState();
+ mFlags = k.getFlags();
+ mKeyCode = k.getKeyCode();
+ mUnicodeChar = k.getUnicodeChar();
+ mCharacters = k.getCharacters();
+ }
+
+ public GeckoEvent(MotionEvent m) {
+ mType = MOTION_EVENT;
+ mAction = m.getAction();
+ mTime = m.getEventTime();
+ mP0 = new Point((int)m.getX(), (int)m.getY());
+ }
+
+ public GeckoEvent(SensorEvent s) {
+ mType = SENSOR_EVENT;
+ mX = s.values[0] / SensorManager.GRAVITY_EARTH;
+ mY = s.values[1] / SensorManager.GRAVITY_EARTH;
+ mZ = s.values[2] / SensorManager.GRAVITY_EARTH;
+ }
+
+ public GeckoEvent(boolean batchEdit, String text) {
+ mType = IME_EVENT;
+ if (text != null)
+ mAction = IME_SET_TEXT;
+ else
+ mAction = batchEdit ? IME_BATCH_BEGIN : IME_BATCH_END;
+ mCharacters = text;
+ }
+
+ public GeckoEvent(boolean forward, int count) {
+ mType = IME_EVENT;
+ mAction = IME_GET_TEXT;
+ if (forward)
+ mCount = count;
+ else
+ mCount2 = count;
+ }
+
+ public GeckoEvent(int leftLen, int rightLen) {
+ mType = IME_EVENT;
+ mAction = IME_DELETE_TEXT;
+ mCount = leftLen;
+ mCount2 = rightLen;
+ }
+
+ public GeckoEvent(int etype, Rect dirty) {
+ if (etype != DRAW) {
+ mType = INVALID;
+ return;
+ }
+
+ mType = etype;
+ mRect = dirty;
+ }
+
+ public GeckoEvent(int etype, int w, int h, int oldw, int oldh) {
+ if (etype != SIZE_CHANGED) {
+ mType = INVALID;
+ return;
+ }
+
+ mType = etype;
+
+ mP0 = new Point(w, h);
+ mP1 = new Point(oldw, oldh);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/embedding/android/GeckoSurfaceView.java
@@ -0,0 +1,838 @@
+/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Vladimir Vukicevic <vladimir@pobox.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 ***** */
+
+package org.mozilla.gecko;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+import java.util.concurrent.atomic.*;
+import java.util.zip.*;
+import java.nio.*;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGL11;
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import javax.microedition.khronos.egl.EGLSurface;
+import javax.microedition.khronos.opengles.GL;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.os.*;
+import android.app.*;
+import android.text.*;
+import android.view.*;
+import android.view.inputmethod.*;
+import android.content.*;
+import android.graphics.*;
+import android.widget.*;
+import android.hardware.*;
+
+import android.util.*;
+
+/*
+ * GeckoSurfaceView implements a GL surface view,
+ * similar to GLSurfaceView. However, since we
+ * already have a thread for Gecko, we don't really want
+ * a separate renderer thread that GLSurfaceView provides.
+ */
+class GeckoSurfaceView
+ extends SurfaceView
+ implements SurfaceHolder.Callback, SensorEventListener
+{
+ public GeckoSurfaceView(Context context) {
+ super(context);
+
+ getHolder().addCallback(this);
+ inputConnection = new GeckoInputConnection(this);
+ setFocusable(true);
+ setFocusableInTouchMode(true);
+
+ if (!GeckoApp.useSoftwareDrawing)
+ startEgl();
+
+ mWidth = 0;
+ mHeight = 0;
+ mBufferWidth = 0;
+ mBufferHeight = 0;
+
+ mSurfaceLock = new ReentrantLock();
+ }
+
+ protected void finalize() throws Throwable {
+ super.finalize();
+ if (!GeckoApp.useSoftwareDrawing)
+ finishEgl();
+ }
+
+ private static final int EGL_OPENGL_ES2_BIT = 4;
+ private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
+
+ private void printConfig(EGL10 egl, EGLDisplay display,
+ EGLConfig config) {
+ int[] attributes = {
+ EGL10.EGL_BUFFER_SIZE,
+ EGL10.EGL_ALPHA_SIZE,
+ EGL10.EGL_BLUE_SIZE,
+ EGL10.EGL_GREEN_SIZE,
+ EGL10.EGL_RED_SIZE,
+ EGL10.EGL_DEPTH_SIZE,
+ EGL10.EGL_STENCIL_SIZE,
+ EGL10.EGL_CONFIG_CAVEAT,
+ EGL10.EGL_CONFIG_ID,
+ EGL10.EGL_LEVEL,
+ EGL10.EGL_MAX_PBUFFER_HEIGHT,
+ EGL10.EGL_MAX_PBUFFER_PIXELS,
+ EGL10.EGL_MAX_PBUFFER_WIDTH,
+ EGL10.EGL_NATIVE_RENDERABLE,
+ EGL10.EGL_NATIVE_VISUAL_ID,
+ EGL10.EGL_NATIVE_VISUAL_TYPE,
+ 0x3030, // EGL10.EGL_PRESERVED_RESOURCES,
+ EGL10.EGL_SAMPLES,
+ EGL10.EGL_SAMPLE_BUFFERS,
+ EGL10.EGL_SURFACE_TYPE,
+ EGL10.EGL_TRANSPARENT_TYPE,
+ EGL10.EGL_TRANSPARENT_RED_VALUE,
+ EGL10.EGL_TRANSPARENT_GREEN_VALUE,
+ EGL10.EGL_TRANSPARENT_BLUE_VALUE,
+ 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB,
+ 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA,
+ 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL,
+ 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL,
+ EGL10.EGL_LUMINANCE_SIZE,
+ EGL10.EGL_ALPHA_MASK_SIZE,
+ EGL10.EGL_COLOR_BUFFER_TYPE,
+ EGL10.EGL_RENDERABLE_TYPE,
+ 0x3042 // EGL10.EGL_CONFORMANT
+ };
+ String[] names = {
+ "EGL_BUFFER_SIZE",
+ "EGL_ALPHA_SIZE",
+ "EGL_BLUE_SIZE",
+ "EGL_GREEN_SIZE",
+ "EGL_RED_SIZE",
+ "EGL_DEPTH_SIZE",
+ "EGL_STENCIL_SIZE",
+ "EGL_CONFIG_CAVEAT",
+ "EGL_CONFIG_ID",
+ "EGL_LEVEL",
+ "EGL_MAX_PBUFFER_HEIGHT",
+ "EGL_MAX_PBUFFER_PIXELS",
+ "EGL_MAX_PBUFFER_WIDTH",
+ "EGL_NATIVE_RENDERABLE",
+ "EGL_NATIVE_VISUAL_ID",
+ "EGL_NATIVE_VISUAL_TYPE",
+ "EGL_PRESERVED_RESOURCES",
+ "EGL_SAMPLES",
+ "EGL_SAMPLE_BUFFERS",
+ "EGL_SURFACE_TYPE",
+ "EGL_TRANSPARENT_TYPE",
+ "EGL_TRANSPARENT_RED_VALUE",
+ "EGL_TRANSPARENT_GREEN_VALUE",
+ "EGL_TRANSPARENT_BLUE_VALUE",
+ "EGL_BIND_TO_TEXTURE_RGB",
+ "EGL_BIND_TO_TEXTURE_RGBA",
+ "EGL_MIN_SWAP_INTERVAL",
+ "EGL_MAX_SWAP_INTERVAL",
+ "EGL_LUMINANCE_SIZE",
+ "EGL_ALPHA_MASK_SIZE",
+ "EGL_COLOR_BUFFER_TYPE",
+ "EGL_RENDERABLE_TYPE",
+ "EGL_CONFORMANT"
+ };
+ int[] value = new int[1];
+ for (int i = 0; i < attributes.length; i++) {
+ int attribute = attributes[i];
+ String name = names[i];
+ if ( egl.eglGetConfigAttrib(display, config, attribute, value)) {
+ Log.w("GeckoAppJava", String.format(" %s: %d\n", name, value[0]));
+ } else {
+ Log.w("GeckoAppJava", String.format(" %s: failed\n", name));
+ // while (egl.eglGetError() != EGL10.EGL_SUCCESS);
+ }
+ }
+ }
+
+ public void startEgl() {
+ if (mEgl != null)
+ return;
+
+ mEgl = (EGL10) EGLContext.getEGL();
+ mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+
+ // initialize egl
+ int[] version = new int[2];
+ mEgl.eglInitialize(mEglDisplay, version);
+
+ // flip this to true to dump all the EGL configs
+ if (false) {
+ int[] cs = { EGL10.EGL_NONE };
+ int[] ptrnum = new int[1];
+
+ mEgl.eglChooseConfig(mEglDisplay, cs, null, 0, ptrnum);
+
+ int num = ptrnum[0];
+ EGLConfig[] confs = new EGLConfig[num];
+
+ mEgl.eglChooseConfig(mEglDisplay, cs, confs, num, ptrnum);
+
+ for (int i = 0; i < num; ++i) {
+ Log.w("GeckoAppJava", "=== EGL config " + i + " ===");
+ printConfig(mEgl, mEglDisplay, confs[i]);
+ }
+ }
+ }
+
+ public void finishEgl() {
+ if (mEglDisplay != null) {
+ mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
+ EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
+ }
+
+ if (mEglContext != null) {
+ mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+ mEglContext = null;
+ }
+
+ if (mEglSurface != null) {
+ mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+ mEglSurface = null;
+ }
+
+ if (mEglDisplay != null) {
+ mEgl.eglTerminate(mEglDisplay);
+ mEglDisplay = null;
+ }
+
+ mEglConfig = null;
+ mEgl = null;
+
+ mSurfaceChanged = false;
+ }
+
+ public void chooseEglConfig() {
+ int redBits, greenBits, blueBits, alphaBits;
+
+ // There are some shenanigans here.
+ // We're required to choose an exact EGL config to match
+ // the surface format, or we get an error. However,
+ // on Droid at least, the format is -1, which is PixelFormat.OPAQUE.
+ // That's not a valid format to be reported; that should just be a
+ // valid value for *setFormat*. We have a catch-all case that
+ // assumes 565 for those cases, but it's pretty ugly.
+
+ Log.i("GeckoAppJava", "GeckoView PixelFormat format is " + mFormat);
+ if (mFormat == PixelFormat.RGB_565) {
+ redBits = 5;
+ greenBits = 6;
+ blueBits = 5;
+ alphaBits = 0;
+ } else if (mFormat == PixelFormat.RGB_888 ||
+ mFormat == PixelFormat.RGBX_8888)
+ {
+ redBits = 8;
+ greenBits = 8;
+ blueBits = 8;
+ alphaBits = 0;
+ } else if (mFormat == PixelFormat.RGBA_8888) {
+ redBits = 8;
+ greenBits = 8;
+ blueBits = 8;
+ alphaBits = 8;
+ } else {
+ Log.w("GeckoAppJava", "Unknown PixelFormat for surface (format is " + mFormat + "), assuming 5650!");
+ redBits = 5;
+ greenBits = 6;
+ blueBits = 5;
+ alphaBits = 0;
+ }
+
+ // PowerVR SGX (Droid) seems to really want depth == 24 for
+ // performance, even 0 is slower. However, other platforms,
+ // like Tegra, don't -have- a 24 bit depth config (have 16).
+ // So that's not good. We'll try with 24 first, and if
+ // nothing, then we'll go to 0. I'm not sure what the nexus
+ // one chip wants.
+
+ int[] confSpec = new int[] {
+ // DEPTH_SIZE must be the first pair
+ EGL10.EGL_DEPTH_SIZE, 24,
+ EGL10.EGL_RED_SIZE, redBits,
+ EGL10.EGL_GREEN_SIZE, greenBits,
+ EGL10.EGL_BLUE_SIZE, blueBits,
+ EGL10.EGL_ALPHA_SIZE, alphaBits,
+ EGL10.EGL_STENCIL_SIZE, 0,
+ EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_NONE,
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE };
+
+ // so tortured to pass an int as an out param...
+ int[] ptrNumConfigs = new int[1];
+ mEgl.eglChooseConfig(mEglDisplay, confSpec, null, 0, ptrNumConfigs);
+
+ int numConfigs = ptrNumConfigs[0];
+
+ if (numConfigs == 0) {
+ // twiddle the DEPTH_SIZE value
+ confSpec[1] = 0;
+ Log.i("GeckoAppJava", "Couldn't find any valid EGL configs with 24 bit depth, trying 0.");
+
+ mEgl.eglChooseConfig(mEglDisplay, confSpec, null, 0, ptrNumConfigs);
+ numConfigs = ptrNumConfigs[0];
+ }
+
+ if (numConfigs <= 0) {
+ // couldn't find a config?
+ Log.w("GeckoAppJava", "Couldn't find any valid EGL configs, blindly trying them all!");
+
+ int[] fallbackConfSpec = new int[] {
+ EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL10.EGL_NONE };
+ confSpec = fallbackConfSpec;
+
+ mEgl.eglChooseConfig(mEglDisplay, confSpec, null, 0, ptrNumConfigs);
+ numConfigs = ptrNumConfigs[0];
+
+ if (numConfigs == 0) {
+ Log.e("GeckoAppJava", "There aren't any EGL configs available on this system.");
+ finishEgl();
+ mSurfaceValid = false;
+ return;
+ }
+ }
+
+ EGLConfig[] configs = new EGLConfig[numConfigs];
+ mEgl.eglChooseConfig(mEglDisplay, confSpec, configs, numConfigs, ptrNumConfigs);
+
+ // Find the first config that has the exact RGB sizes that we
+ // need for our window surface.
+ int[] ptrVal = new int[1];
+ for (int i = 0; i < configs.length; ++i) {
+ int confRed = -1, confGreen = -1, confBlue = -1, confAlpha = -1;
+
+ if (mEgl.eglGetConfigAttrib(mEglDisplay, configs[i], EGL10.EGL_RED_SIZE, ptrVal))
+ confRed = ptrVal[0];
+ if (mEgl.eglGetConfigAttrib(mEglDisplay, configs[i], EGL10.EGL_GREEN_SIZE, ptrVal))
+ confGreen = ptrVal[0];
+ if (mEgl.eglGetConfigAttrib(mEglDisplay, configs[i], EGL10.EGL_BLUE_SIZE, ptrVal))
+ confBlue = ptrVal[0];
+ if (mEgl.eglGetConfigAttrib(mEglDisplay, configs[i], EGL10.EGL_ALPHA_SIZE, ptrVal))
+ confAlpha = ptrVal[0];
+
+ if (confRed == redBits &&
+ confGreen == greenBits &&
+ confBlue == blueBits &&
+ confAlpha == alphaBits)
+ {
+ mEglConfig = configs[i];
+ break;
+ }
+ }
+
+ if (mEglConfig == null) {
+ Log.w("GeckoAppJava", "Couldn't find EGL config matching colors; using first, hope it works!");
+ mEglConfig = configs[0];
+ }
+
+ Log.i("GeckoAppJava", "====== Chosen config: ======");
+ printConfig(mEgl, mEglDisplay, mEglConfig);
+
+ mEglContext = null;
+ mEglSurface = null;
+ }
+
+ /*
+ * Called on main thread
+ */
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ mSurfaceLock.lock();
+
+ try {
+ if (mInDrawing) {
+ Log.w("GeckoAppJava", "surfaceChanged while mInDrawing is true!");
+ }
+
+ mFormat = format;
+ mWidth = width;
+ mHeight = height;
+ mSurfaceValid = true;
+
+ Log.i("GeckoAppJava", "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
+
+ if (!GeckoApp.useSoftwareDrawing) {
+ chooseEglConfig();
+ }
+
+ // XXX This code doesn't seem to actually get hit
+ if (!GeckoAppShell.sGeckoRunning) {
+ GeckoAppShell.setInitialSize(width, height);
+ return;
+ }
+
+ GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height, -1, -1);
+ GeckoAppShell.sendEventToGecko(e);
+
+ if (mSurfaceNeedsRedraw) {
+ GeckoAppShell.scheduleRedraw();
+ mSurfaceNeedsRedraw = false;
+ }
+
+ mSurfaceChanged = true;
+
+ //Log.i("GeckoAppJava", "<< surfaceChanged");
+ } finally {
+ mSurfaceLock.unlock();
+ }
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ if (GeckoAppShell.sGeckoRunning)
+ mSurfaceNeedsRedraw = true;
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ Log.i("GeckoAppJava", "surface destroyed");
+ mSurfaceValid = false;
+ }
+
+ public ByteBuffer getSoftwareDrawBuffer() {
+ //#ifdef DEBUG
+ if (!mSurfaceLock.isHeldByCurrentThread())
+ Log.e("GeckoAppJava", "getSoftwareDrawBuffer called outside of mSurfaceLock!");
+ //#endif
+
+ return mSoftwareBuffer;
+ }
+
+ /*
+ * Called on Gecko thread
+ */
+
+ public static final int DRAW_ERROR = 0;
+ public static final int DRAW_GLES_2 = 1;
+ public static final int DRAW_SOFTWARE = 2;
+
+ int innerBeginDrawing() {
+ /*
+ * Software (non-GL) rendering
+ */
+ if (GeckoApp.useSoftwareDrawing) {
+ if (mWidth != mBufferWidth ||
+ mHeight != mBufferHeight ||
+ mSurfaceChanged)
+ {
+ if (mWidth*mHeight != mBufferWidth*mBufferHeight)
+ mSoftwareBuffer = ByteBuffer.allocateDirect(mWidth*mHeight*4);
+
+ mSoftwareBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
+
+ mBufferWidth = mWidth;
+ mBufferHeight = mHeight;
+ mSurfaceChanged = false;
+ }
+
+ mSoftwareCanvas = getHolder().lockCanvas(null);
+ if (mSoftwareCanvas == null) {
+ Log.e("GeckoAppJava", "lockCanvas failed! << beginDrawing");
+ return DRAW_ERROR;
+ }
+
+ return DRAW_SOFTWARE;
+ }
+
+ /*
+ * GL rendering
+ */
+
+ if (mEgl == null || mEglDisplay == null || mEglConfig == null) {
+ Log.e("GeckoAppJava", "beginDrawing called, but EGL was never initialized!");
+
+ mSurfaceLock.unlock();
+ return DRAW_ERROR;
+ }
+
+ /*
+ * If the surface doesn't exist, or if its dimensions or something else changed,
+ * recreate it.
+ */
+ if (mEglSurface == null ||
+ mWidth != mBufferWidth ||
+ mHeight != mBufferHeight ||
+ mSurfaceChanged)
+ {
+ if (mEglContext != null) {
+ mEgl.eglDestroyContext(mEglDisplay, mEglContext);
+ mEglContext = null;
+ }
+
+ if (mEglSurface != null)
+ mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
+
+ mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, getHolder(), null);
+ if (mEglSurface == EGL10.EGL_NO_SURFACE)
+ {
+ Log.e("GeckoAppJava", "eglCreateWindowSurface failed!");
+ mSurfaceValid = false;
+ return DRAW_ERROR;
+ }
+
+ mBufferWidth = mWidth;
+ mBufferHeight = mHeight;
+
+ mSurfaceChanged = false;
+ }
+
+ if (mEglContext == null) {
+ int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2,
+ EGL10.EGL_NONE };
+ mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
+ if (mEglContext == EGL10.EGL_NO_CONTEXT)
+ {
+ Log.e("GeckoAppJava", "eglCreateContext failed! " + mEgl.eglGetError());
+ mSurfaceValid = false;
+ return DRAW_ERROR;
+ }
+
+ Log.i("GeckoAppJava", "EglContext created");
+ }
+
+ // Hmm, should we issue this makecurrent for each frame?
+ // We'll likely have to, as other bits might switch the context (e.g.
+ // WebGL, video, etc.).
+
+ if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+ int err = mEgl.eglGetError();
+ Log.e("GeckoAppJava", "eglMakeCurrent failed! " + err);
+ return DRAW_ERROR;
+ }
+
+ return DRAW_GLES_2;
+ }
+
+ public int beginDrawing() {
+ //Log.i("GeckoAppJava", ">> beginDrawing");
+
+ if (mInDrawing) {
+ Log.e("GeckoAppJava", "Recursive beginDrawing call!");
+ return DRAW_ERROR;
+ }
+
+ /* Grab the lock, which we'll hold while we're drawing.
+ * It gets released in endDrawing(), and is also used in surfaceChanged
+ * to make sure that we don't change our surface details while
+ * we're in the middle of drawing (and especially in the middle of
+ * executing beginDrawing/endDrawing).
+ *
+ * We might not need to hold this lock in between
+ * beginDrawing/endDrawing, and might just be able to make
+ * surfaceChanged, beginDrawing, and endDrawing synchronized,
+ * but this way is safer for now.
+ */
+ mSurfaceLock.lock();
+
+ if (!mSurfaceValid) {
+ Log.e("GeckoAppJava", "Surface not valid");
+ mSurfaceLock.unlock();
+ return DRAW_ERROR;
+ }
+
+ // call the inner function to do the work, so we can sanely unlock on error
+ int result = innerBeginDrawing();
+
+ if (result == DRAW_ERROR) {
+ mSurfaceLock.unlock();
+ return DRAW_ERROR;
+ }
+
+ mInDrawing = true;
+ return result;
+ }
+
+ public void endDrawing() {
+ //Log.w("GeckoAppJava", ">> endDrawing");
+
+ if (!mInDrawing) {
+ Log.e("GeckoAppJava", "endDrawing without beginDrawing!");
+ return;
+ }
+
+ try {
+ if (!mSurfaceValid) {
+ Log.e("GeckoAppJava", "endDrawing with false mSurfaceValid");
+ return;
+ }
+
+ if (GeckoApp.useSoftwareDrawing) {
+ if (!mSurfaceChanged) {
+ mSoftwareBitmap.copyPixelsFromBuffer(mSoftwareBuffer);
+ mSoftwareCanvas.drawBitmap(mSoftwareBitmap, 0, 0, null);
+
+ getHolder().unlockCanvasAndPost(mSoftwareCanvas);
+ mSoftwareCanvas = null;
+ }
+ } else {
+ // If the surface was changed while we were drawing;
+ // don't even bother trying to swap, it won't work,
+ // and may cause further problems. Note that
+ // eglSwapBuffers might also throw an
+ // IllegalArgumentException; we catch that as well.
+ if (!mSurfaceChanged) {
+ mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
+ if (mEgl.eglGetError() == EGL11.EGL_CONTEXT_LOST)
+ mSurfaceChanged = true;
+ }
+ }
+ } catch (java.lang.IllegalArgumentException ex) {
+ mSurfaceChanged = true;
+ } finally {
+ mInDrawing = false;
+
+ //#ifdef DEBUG
+ if (!mSurfaceLock.isHeldByCurrentThread())
+ Log.e("GeckoAppJava", "endDrawing while mSurfaceLock not held by current thread!");
+ //#endif
+
+ mSurfaceLock.unlock();
+ }
+ }
+
+ @Override
+ public boolean onCheckIsTextEditor () {
+ return false;
+ }
+
+ @Override
+ public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
+ outAttrs.inputType = InputType.TYPE_CLASS_TEXT |
+ InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
+ return inputConnection;
+ }
+
+ public void onAccuracyChanged(Sensor sensor, int accuracy)
+ {
+ }
+
+ public void onSensorChanged(SensorEvent event)
+ {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
+ }
+
+ // event stuff
+ public boolean onTouchEvent(MotionEvent event) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
+ return true;
+ }
+
+ // Is this surface valid for drawing into?
+ boolean mSurfaceValid;
+
+ // Do we need to force a redraw on surfaceChanged?
+ boolean mSurfaceNeedsRedraw;
+
+ // Has this surface been changed? (That is,
+ // do we need to recreate buffers?)
+ boolean mSurfaceChanged;
+
+ // Are we actively between beginDrawing/endDrawing?
+ boolean mInDrawing;
+
+ // let's not change stuff around while we're in the middle of
+ // starting drawing, ending drawing, or changing surface
+ // characteristics
+ ReentrantLock mSurfaceLock;
+
+ // Surface format, from surfaceChanged. Largely
+ // useless.
+ int mFormat;
+
+ // the dimensions of the surface
+ int mWidth;
+ int mHeight;
+
+ // the dimensions of the buffer we're using for drawing,
+ // that is the software buffer or the EGLSurface
+ int mBufferWidth;
+ int mBufferHeight;
+
+ // IME stuff
+ GeckoInputConnection inputConnection;
+ int mIMEState;
+
+ // Software rendering
+ ByteBuffer mSoftwareBuffer;
+ Bitmap mSoftwareBitmap;
+ Canvas mSoftwareCanvas;
+
+ // GL rendering
+ EGL10 mEgl;
+ EGLDisplay mEglDisplay;
+ EGLSurface mEglSurface;
+ EGLConfig mEglConfig;
+ EGLContext mEglContext;
+}
+
+class GeckoInputConnection
+ extends BaseInputConnection
+{
+ public GeckoInputConnection (View targetView) {
+ super(targetView, true);
+ mQueryResult = new SynchronousQueue<String>();
+ mExtractedText.partialStartOffset = -1;
+ mExtractedText.partialEndOffset = -1;
+ }
+
+ @Override
+ public Editable getEditable() {
+ Log.i("GeckoAppJava", "getEditable");
+ return null;
+ }
+
+ @Override
+ public boolean beginBatchEdit() {
+ if (mComposing)
+ return true;
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(true, null));
+ mComposing = true;
+ return true;
+ }
+ @Override
+ public boolean commitCompletion(CompletionInfo text) {
+ Log.i("GeckoAppJava", "Stub: commitCompletion");
+ return true;
+ }
+ @Override
+ public boolean commitText(CharSequence text, int newCursorPosition) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(true, text.toString()));
+ endBatchEdit();
+ return true;
+ }
+ @Override
+ public boolean deleteSurroundingText(int leftLength, int rightLength) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(leftLength, rightLength));
+ updateExtractedText();
+ return true;
+ }
+ @Override
+ public boolean endBatchEdit() {
+ updateExtractedText();
+ if (!mComposing)
+ return true;
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(false, null));
+ mComposing = false;
+ return true;
+ }
+ @Override
+ public boolean finishComposingText() {
+ endBatchEdit();
+ return true;
+ }
+ @Override
+ public int getCursorCapsMode(int reqModes) {
+ return 0;
+ }
+ @Override
+ public ExtractedText getExtractedText(ExtractedTextRequest req, int flags) {
+ mExtractToken = req.token;
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(false, 0));
+ try {
+ mExtractedText.text = mQueryResult.take();
+ mExtractedText.selectionStart = mSelectionStart;
+ mExtractedText.selectionEnd = mSelectionEnd;
+ } catch (InterruptedException e) {
+ Log.i("GeckoAppJava", "getExtractedText: Interrupted!");
+ }
+ return mExtractedText;
+ }
+ @Override
+ public CharSequence getTextAfterCursor(int length, int flags) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(true, length));
+ try {
+ String result = mQueryResult.take();
+ return result;
+ } catch (InterruptedException e) {
+ Log.i("GeckoAppJava", "getTextAfterCursor: Interrupted!");
+ }
+ return null;
+ }
+ @Override
+ public CharSequence getTextBeforeCursor(int length, int flags) {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(false, length));
+ try {
+ String result = mQueryResult.take();
+ return result;
+ } catch (InterruptedException e) {
+ Log.i("GeckoAppJava", "getTextBeforeCursor: Interrupted!");
+ }
+ return null;
+ }
+ @Override
+ public boolean setComposingText(CharSequence text, int newCursorPosition) {
+ beginBatchEdit();
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(true, text.toString()));
+ return true;
+ }
+ @Override
+ public boolean setSelection(int start, int end) {
+ Log.i("GeckoAppJava", "Stub: setSelection " + start + " " + end);
+ return true;
+ }
+
+ private void updateExtractedText() {
+ GeckoAppShell.sendEventToGecko(new GeckoEvent(false, 0));
+ try {
+ mExtractedText.text = mQueryResult.take();
+ mExtractedText.selectionStart = mSelectionStart;
+ mExtractedText.selectionEnd = mSelectionEnd;
+ } catch (InterruptedException e) {
+ Log.i("GeckoAppJava", "getExtractedText: Interrupted!");
+ }
+
+ InputMethodManager imm = (InputMethodManager)
+ GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.updateExtractedText(GeckoApp.surfaceView, mExtractToken, mExtractedText);
+ }
+
+ boolean mComposing;
+ int mExtractToken;
+ final ExtractedText mExtractedText = new ExtractedText();
+
+ int mSelectionStart, mSelectionEnd;
+ SynchronousQueue<String> mQueryResult;
+}
new file mode 100644
--- /dev/null
+++ b/embedding/android/Makefile.in
@@ -0,0 +1,182 @@
+# ***** 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 the Mozilla browser.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2009-2010
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Vladimir Vukicevic <vladimir@pobox.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 *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DX=$(ANDROID_SDK)/tools/dx
+AAPT=$(ANDROID_SDK)/tools/aapt
+APKBUILDER=$(ANDROID_SDK)/../../tools/apkbuilder
+ZIPALIGN=$(ANDROID_SDK)/../../tools/zipalign
+
+JAVAFILES = \
+ GeckoApp.java \
+ GeckoAppShell.java \
+ GeckoEvent.java \
+ GeckoSurfaceView.java \
+ $(NULL)
+
+DEFINES += \
+ -DMOZ_APP_DISPLAYNAME=$(MOZ_APP_DISPLAYNAME) \
+ -DMOZ_APP_NAME=$(MOZ_APP_NAME)
+
+GARBAGE += \
+ AndroidManifest.xml \
+ classes.dex \
+ $(MOZ_APP_NAME).apk \
+ App.java \
+ Restarter.java \
+ gecko.ap_ \
+ gecko-unaligned.apk \
+ gecko-unsigned-unaligned.apk \
+ $(NULL)
+
+GARBAGE_DIRS += res libs dist classes
+
+ifdef JARSIGNER
+ APKBUILDER_FLAGS += -u
+endif
+
+# Bug 567884 - Need a way to find appropriate icons during packaging
+ifeq ($(MOZ_APP_NAME),fennec)
+ICON_PATH = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/fennec_48x48.png
+ICON_PATH_HI = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/fennec_72x72.png
+else
+ICON_PATH = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/icon48.png
+ICON_PATH_HI = $(topsrcdir)/$(MOZ_BRANDING_DIRECTORY)/content/icon64.png
+endif
+
+NATIVE_LIBS = $(shell cat $(DIST)/bin/dependentlibs.list) libxpcom.so libnssckbi.so libfreebl3.so
+FULL_LIBS = $(addprefix libs/armeabi/,$(NATIVE_LIBS))
+
+# We'll strip all the libs by default, due to size, but we might
+# want to have a non-stripped version for debugging. We should
+# really pull out debuginfo and stuff.
+ifdef NO_STRIP
+DO_STRIP=echo not stripping
+else
+DO_STRIP=$(STRIP)
+endif
+
+# The set of files/directories from the dist/bin dir that we'll make available in the apk
+# some directories not listed due to special handling
+DIST_LINK_FILES = \
+ modules \
+ res \
+ application.ini \
+ platform.ini \
+ greprefs.js \
+ browserconfig.properties \
+ blocklist.xml \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+# rules.mk has some java stuff, but we're going to ignore it for now
+JAVAC_FLAGS = \
+ -target 1.5 \
+ -classpath $(ANDROID_SDK)/android.jar \
+ -bootclasspath $(ANDROID_SDK)/android.jar \
+ -encoding ascii \
+ -g \
+ $(NULL)
+
+tools:: $(MOZ_APP_NAME).apk
+
+# Note that we're going to set up a dependency directly between embed_android.dex and the java files
+# Instead of on the .class files, since more than one .class file might be produced per .java file
+classes.dex: $(JAVAFILES) App.java Restarter.java
+ $(NSINSTALL) -D classes
+ $(JAVAC) $(JAVAC_FLAGS) -d classes $(addprefix $(srcdir)/,$(JAVAFILES)) App.java Restarter.java
+ $(DX) --dex --output=$@ classes
+
+AndroidManifest.xml App.java Restarter.java : % : %.in
+ $(PYTHON) $(topsrcdir)/config/Preprocessor.py \
+ $(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
+
+res/drawable/icon.png: $(MOZ_APP_ICON)
+ $(NSINSTALL) -D res/drawable
+ cp $(ICON_PATH) $@
+
+res/drawable-hdpi/icon.png: $(MOZ_APP_ICON)
+ $(NSINSTALL) -D res/drawable-hdpi
+ cp $(ICON_PATH_HI) $@
+
+gecko.ap_: AndroidManifest.xml res/drawable/icon.png res/drawable-hdpi/icon.png
+ $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -S res -F $@
+
+libs/armeabi/%: $(DIST)/lib/%
+ @$(NSINSTALL) -D libs/armeabi
+ @cp -L -v $< $@
+ @$(DO_STRIP) $@
+
+# Bug 567873 - Android packaging should use standard packaging code
+dist: FORCE
+ $(NSINSTALL) -D dist/components
+ rm -f dist/components/*
+ @(for f in $(DIST)/bin/components/* ; do ln -sf ../../$$f dist/components ; done)
+ $(DIST)/host/bin/host_xpt_link gecko.xpt dist/components/*.xpt
+ rm dist/components/*.xpt
+ mv gecko.xpt dist/components
+ $(NSINSTALL) -D dist/chrome
+ rm -f dist/chrome/*
+ @(for f in $(DIST)/bin/chrome/* ; do ln -sf ../../$$f dist/chrome ; done)
+ @(for MANIFEST in dist/chrome/*.manifest ; do cat "$$MANIFEST" >> chrome.manifest ; echo >> chrome.manifest; rm "$$MANIFEST" ; done )
+ mv chrome.manifest dist/chrome/
+ $(NSINSTALL) -D dist/defaults
+ rm -f dist/defaults/*
+ @(for f in $(DIST)/bin/defaults/* ; do ln -sf ../../$$f dist/defaults ; done )
+ @(for PREF in $(DIST)/bin/defaults/pref/*.js ; do cat "$$PREF" >> dist/defaults/prefs.js ; echo >> dist/defaults/prefs.js ; done )
+ rm dist/defaults/pref
+ @(for f in $(DIST_LINK_FILES) ; do if [ -e $(DIST)/bin/$$f ] ; then echo $$f ; ln -sf ../$(DIST)/bin/$$f dist ; fi ; done)
+
+gecko-unsigned-unaligned.apk: gecko.ap_ classes.dex dist $(FULL_LIBS)
+ $(APKBUILDER) $@ -v $(APKBUILDER_FLAGS) -z gecko.ap_ -f classes.dex -nf `pwd`/libs -rf dist
+
+gecko-unaligned.apk: gecko-unsigned-unaligned.apk
+ cp gecko-unsigned-unaligned.apk $@
+ifdef JARSIGNER
+ $(JARSIGNER) $@
+endif
+
+$(MOZ_APP_NAME).apk: gecko-unaligned.apk
+ $(ZIPALIGN) -f -v 4 gecko-unaligned.apk $@
+
new file mode 100644
--- /dev/null
+++ b/embedding/android/Restarter.java.in
@@ -0,0 +1,91 @@
+/* -*- Mode: Java; tab-width: 20; indent-tabs-mode: nil; -*-
+ * ***** 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 Android code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Brad Lassey <blassey@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 ***** */
+
+#filter substitution
+package org.mozilla.@MOZ_APP_NAME@;
+
+import android.content.*;
+import android.util.Log;
+import java.io.*;
+
+public class Restarter extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.i("Restarter", "trying to restart @MOZ_APP_NAME@");
+ try {
+ boolean stillRunning;
+ do {
+ stillRunning = false;
+ Process p = Runtime.getRuntime().exec("/system/bin/ps");
+ BufferedReader psOut = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line;
+ Log.i("Restarter", "pid: " + new Integer(android.os.Process.myPid()).toString());
+ while((line = psOut.readLine()) != null) {
+ Log.i("Restarter", "ps: " + line);
+ if (line.contains("org.mozilla.@MOZ_APP_NAME@.App")){
+ if (!line.contains(new Integer(android.os.Process.myPid()).toString())){
+ Log.i("Restarter", "app still running, wait a bit");
+ stillRunning = true;
+ Thread.sleep(500);
+ break; // don't need to look at the rest
+ } else {
+ Log.i("Restarter", "found ourselves");
+ }
+ }
+ }
+ } while(stillRunning);
+ } catch (Exception e) {
+ Log.i("Restarter", e.toString());
+ }
+ try {
+ String action = "android.intent.action.MAIN";
+ String env;
+ StringBuffer envstr = new StringBuffer();
+ for (int c = 0; (env = intent.getStringExtra("env" + c)) != null; c++) {
+ envstr.append(" --es env" + c + " " + env);
+ }
+ String amCmd = "/system/bin/am start -a " + action + envstr.toString() +
+ " -n org.mozilla.@MOZ_APP_NAME@/org.mozilla.@MOZ_APP_NAME@.App";
+ Log.i("Restarter", amCmd);
+
+ Runtime.getRuntime().exec(amCmd);
+ } catch (Exception e) {
+ Log.i("Restarter", e.toString());
+ }
+ System.exit(0);
+ }
+};
--- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp
+++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp
@@ -70,20 +70,31 @@
#include "nsUnicharUtilCIID.h"
#include "nsUnicharUtils.h"
#include "nsCRT.h"
#include <stdlib.h>
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
-NS_IMPL_ISUPPORTS3(mozHunspell,
- mozISpellCheckingEngine,
- nsIObserver,
- nsISupportsWeakReference)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell)
+
+NS_INTERFACE_MAP_BEGIN(mozHunspell)
+ NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozHunspell)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
+ mPersonalDictionary,
+ mEncoder,
+ mDecoder)
nsresult
mozHunspell::Init()
{
if (!mDictionaries.Init())
return NS_ERROR_OUT_OF_MEMORY;
LoadDictionaryList();
--- a/extensions/spellcheck/hunspell/src/mozHunspell.h
+++ b/extensions/spellcheck/hunspell/src/mozHunspell.h
@@ -64,31 +64,33 @@
#include "mozIPersonalDictionary.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsInterfaceHashtable.h"
#include "nsWeakReference.h"
+#include "nsCycleCollectionParticipant.h"
#define MOZ_HUNSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1"
#define MOZ_HUNSPELL_CID \
/* 56c778e4-1bee-45f3-a689-886692a97fe7 */ \
{ 0x56c778e4, 0x1bee, 0x45f3, \
{ 0xa6, 0x89, 0x88, 0x66, 0x92, 0xa9, 0x7f, 0xe7 } }
class mozHunspell : public mozISpellCheckingEngine,
public nsIObserver,
public nsSupportsWeakReference
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_MOZISPELLCHECKINGENGINE
NS_DECL_NSIOBSERVER
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozHunspell, mozISpellCheckingEngine)
mozHunspell() : mHunspell(nsnull) { }
virtual ~mozHunspell();
nsresult Init();
void LoadDictionaryList();
void LoadDictionariesFromDir(nsIFile* aDir);
--- a/extensions/spellcheck/osxspell/src/mozOSXSpell.h
+++ b/extensions/spellcheck/osxspell/src/mozOSXSpell.h
@@ -40,30 +40,32 @@
#ifndef mozOSXSpell_h__
#define mozOSXSpell_h__
#include "mozISpellCheckingEngine.h"
#include "mozIPersonalDictionary.h"
#include "nsString.h"
#include "nsCOMPtr.h"
+#include "nsCycleCollectionParticipant.h"
// Use the same contract ID as the Hunspell spellchecker so we get picked up
// instead on Mac OS X but we have our own CID.
#define MOZ_OSXSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1"
#define MOZ_OSXSPELL_CID \
{ /* BAABBAF4-71C3-47F4-A576-E75469E485E2 */ \
0xBAABBAF4, 0x71C3, 0x47F4, \
{ 0xA5, 0x76, 0xE7, 0x54, 0x69, 0xE4, 0x85, 0xE2} }
class mozOSXSpell : public mozISpellCheckingEngine
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_MOZISPELLCHECKINGENGINE
+ NS_DECL_CYCLE_COLLECTION_CLASS(mozOSXSpell)
mozOSXSpell();
private:
~mozOSXSpell();
// NSSpellChecker provides the ability to add words to the local dictionary,
--- a/extensions/spellcheck/osxspell/src/mozOSXSpell.mm
+++ b/extensions/spellcheck/osxspell/src/mozOSXSpell.mm
@@ -47,17 +47,26 @@
// utility category we need for PRUnichar<->NSString conversion (taken from Camino)
@interface NSString(PRUnicharUtils)
+ (id)stringWithPRUnichars:(const PRUnichar*)inString;
- (PRUnichar*)createNewUnicodeBuffer;
@end
-NS_IMPL_ISUPPORTS1(mozOSXSpell, mozISpellCheckingEngine)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozOSXSpell)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozOSXSpell)
+
+NS_INTERFACE_MAP_BEGIN(mozOSXSpell)
+ NS_INTERFACE_MAP_ENTRY(mozISpellCheckingEngine)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellCheckingEngine)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozOSXSpell)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_1(mozOSXSpell, mPersonalDictionary);
mozOSXSpell::mozOSXSpell()
{
}
mozOSXSpell::~mozOSXSpell()
{
}
--- a/extensions/spellcheck/src/mozEnglishWordUtils.cpp
+++ b/extensions/spellcheck/src/mozEnglishWordUtils.cpp
@@ -37,17 +37,29 @@
#include "mozEnglishWordUtils.h"
#include "nsICharsetAlias.h"
#include "nsReadableUtils.h"
#include "nsIServiceManager.h"
#include "nsUnicharUtilCIID.h"
#include "nsCRT.h"
-NS_IMPL_ISUPPORTS1(mozEnglishWordUtils, mozISpellI18NUtil)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozEnglishWordUtils)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozEnglishWordUtils)
+
+NS_INTERFACE_MAP_BEGIN(mozEnglishWordUtils)
+ NS_INTERFACE_MAP_ENTRY(mozISpellI18NUtil)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellI18NUtil)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozEnglishWordUtils)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_3(mozEnglishWordUtils,
+ mCaseConv,
+ mCategories,
+ mURLDetector)
mozEnglishWordUtils::mozEnglishWordUtils()
{
mLanguage.AssignLiteral("en");
nsresult rv;
mURLDetector = do_CreateInstance(MOZ_TXTTOHTMLCONV_CONTRACTID, &rv);
mCaseConv = do_GetService(NS_UNICHARUTIL_CONTRACTID);
--- a/extensions/spellcheck/src/mozEnglishWordUtils.h
+++ b/extensions/spellcheck/src/mozEnglishWordUtils.h
@@ -42,22 +42,24 @@
#include "mozISpellI18NUtil.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsString.h"
#include "nsICaseConversion.h"
#include "nsIUGenCategory.h"
#include "mozITXTToHTMLConv.h"
+#include "nsCycleCollectionParticipant.h"
class mozEnglishWordUtils : public mozISpellI18NUtil
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_MOZISPELLI18NUTIL
+ NS_DECL_CYCLE_COLLECTION_CLASS(mozEnglishWordUtils)
mozEnglishWordUtils();
virtual ~mozEnglishWordUtils();
/* additional members */
enum myspCapitalization{
NoCap,InitCap,AllCap,HuhCap
};
--- a/extensions/spellcheck/src/mozGenericWordUtils.cpp
+++ b/extensions/spellcheck/src/mozGenericWordUtils.cpp
@@ -31,17 +31,26 @@
* 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 ***** */
#include "mozGenericWordUtils.h"
-NS_IMPL_ISUPPORTS1(mozGenericWordUtils, mozISpellI18NUtil)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozGenericWordUtils)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozGenericWordUtils)
+
+NS_INTERFACE_MAP_BEGIN(mozGenericWordUtils)
+ NS_INTERFACE_MAP_ENTRY(mozISpellI18NUtil)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellI18NUtil)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozGenericWordUtils)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_0(mozGenericWordUtils)
// do something sensible but generic ... eventually. For now whine.
mozGenericWordUtils::mozGenericWordUtils()
{
/* member initializers and constructor code */
}
--- a/extensions/spellcheck/src/mozGenericWordUtils.h
+++ b/extensions/spellcheck/src/mozGenericWordUtils.h
@@ -35,20 +35,22 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozGenericWordUtils_h__
#define mozGenericWordUtils_h__
#include "nsCOMPtr.h"
#include "mozISpellI18NUtil.h"
+#include "nsCycleCollectionParticipant.h"
class mozGenericWordUtils : public mozISpellI18NUtil
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_MOZISPELLI18NUTIL
+ NS_DECL_CYCLE_COLLECTION_CLASS(mozGenericWordUtils)
mozGenericWordUtils();
virtual ~mozGenericWordUtils();
};
#endif
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -517,20 +517,28 @@ NS_INTERFACE_MAP_BEGIN(mozInlineSpellChe
NS_INTERFACE_MAP_ENTRY(nsIInlineSpellChecker)
NS_INTERFACE_MAP_ENTRY(nsIEditActionListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMFocusListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMKeyListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMKeyListener)
+NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozInlineSpellChecker)
NS_INTERFACE_MAP_END
-NS_IMPL_ADDREF(mozInlineSpellChecker)
-NS_IMPL_RELEASE(mozInlineSpellChecker)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozInlineSpellChecker)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozInlineSpellChecker)
+
+NS_IMPL_CYCLE_COLLECTION_5(mozInlineSpellChecker,
+ mSpellCheck,
+ mTextServicesDocument,
+ mTreeWalker,
+ mConverter,
+ mCurrentSelectionAnchorNode)
mozInlineSpellChecker::SpellCheckingState
mozInlineSpellChecker::gCanEnableSpellChecking =
mozInlineSpellChecker::SpellCheck_Uninitialized;
mozInlineSpellChecker::mozInlineSpellChecker() :
mNumWordsInSpellSelection(0),
mMaxNumWordsInSpellSelection(250),
--- a/extensions/spellcheck/src/mozInlineSpellChecker.h
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.h
@@ -48,16 +48,17 @@
#include "nsIDOMTreeWalker.h"
#include "nsWeakReference.h"
#include "nsIEditor.h"
#include "nsIDOMFocusListener.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMKeyListener.h"
#include "nsWeakReference.h"
#include "mozISpellI18NUtil.h"
+#include "nsCycleCollectionParticipant.h"
class nsIDOMDocumentRange;
class nsIDOMMouseEventListener;
class mozInlineSpellWordUtil;
class mozInlineSpellChecker;
class mozInlineSpellResume;
class mozInlineSpellStatus
@@ -213,19 +214,20 @@ private:
kOpSetAbsolutePosition = 3015,
kOpRemoveAbsolutePosition = 3016,
kOpDecreaseZIndex = 3017,
kOpIncreaseZIndex = 3018
};
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIEDITACTIONLISTENER
NS_DECL_NSIINLINESPELLCHECKER
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozInlineSpellChecker, nsIDOMKeyListener)
// returns true if it looks likely that we can enable real-time spell checking
static PRBool CanEnableInlineSpellChecking();
/*BEGIN implementations of focus event handler interface*/
NS_IMETHOD Focus(nsIDOMEvent* aEvent);
NS_IMETHOD Blur(nsIDOMEvent* aEvent);
/*END implementations of focus event handler interface*/
--- a/extensions/spellcheck/src/mozPersonalDictionary.cpp
+++ b/extensions/spellcheck/src/mozPersonalDictionary.cpp
@@ -63,17 +63,28 @@ const int kMaxWordLen=256;
*
* Allowing personal words to be associated with only certain dictionaries maybe.
*
* TODO:
* Implement the suggestion record.
*/
-NS_IMPL_ISUPPORTS3(mozPersonalDictionary, mozIPersonalDictionary, nsIObserver, nsISupportsWeakReference)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozPersonalDictionary)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozPersonalDictionary)
+
+NS_INTERFACE_MAP_BEGIN(mozPersonalDictionary)
+ NS_INTERFACE_MAP_ENTRY(mozIPersonalDictionary)
+ NS_INTERFACE_MAP_ENTRY(nsIObserver)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozIPersonalDictionary)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozPersonalDictionary)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_1(mozPersonalDictionary, mEncoder)
mozPersonalDictionary::mozPersonalDictionary()
: mDirty(PR_FALSE)
{
}
mozPersonalDictionary::~mozPersonalDictionary()
{
--- a/extensions/spellcheck/src/mozPersonalDictionary.h
+++ b/extensions/spellcheck/src/mozPersonalDictionary.h
@@ -43,16 +43,17 @@
#include "nsVoidArray.h"
#include "mozIPersonalDictionary.h"
#include "nsIUnicodeEncoder.h"
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsTHashtable.h"
#include "nsTArray.h"
#include "nsCRT.h"
+#include "nsCycleCollectionParticipant.h"
#define MOZ_PERSONALDICTIONARY_CONTRACTID "@mozilla.org/spellchecker/personaldictionary;1"
#define MOZ_PERSONALDICTIONARY_CID \
{ /* 7EF52EAF-B7E1-462B-87E2-5D1DBACA9048 */ \
0X7EF52EAF, 0XB7E1, 0X462B, \
{ 0X87, 0XE2, 0X5D, 0X1D, 0XBA, 0XCA, 0X90, 0X48 } }
class nsUniCharEntry : public PLDHashEntryHdr
@@ -87,19 +88,20 @@ private:
};
class mozPersonalDictionary : public mozIPersonalDictionary,
public nsIObserver,
public nsSupportsWeakReference
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_MOZIPERSONALDICTIONARY
NS_DECL_NSIOBSERVER
+ NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozPersonalDictionary, mozIPersonalDictionary)
mozPersonalDictionary();
virtual ~mozPersonalDictionary();
nsresult Init();
protected:
nsTArray<nsString> mDictionary; /* use something a little smarter eventually*/
--- a/extensions/spellcheck/src/mozSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozSpellChecker.cpp
@@ -40,17 +40,29 @@
#include "nsIStringEnumerator.h"
#include "nsICategoryManager.h"
#include "nsISupportsPrimitives.h"
#define UNREASONABLE_WORD_LENGTH 64
#define DEFAULT_SPELL_CHECKER "@mozilla.org/spellchecker/engine;1"
-NS_IMPL_ISUPPORTS1(mozSpellChecker, nsISpellChecker)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozSpellChecker)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozSpellChecker)
+
+NS_INTERFACE_MAP_BEGIN(mozSpellChecker)
+ NS_INTERFACE_MAP_ENTRY(nsISpellChecker)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISpellChecker)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozSpellChecker)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_3(mozSpellChecker,
+ mConverter,
+ mTsDoc,
+ mPersonalDictionary)
mozSpellChecker::mozSpellChecker()
{
}
mozSpellChecker::~mozSpellChecker()
{
if(mPersonalDictionary){
--- a/extensions/spellcheck/src/mozSpellChecker.h
+++ b/extensions/spellcheck/src/mozSpellChecker.h
@@ -43,21 +43,23 @@
#include "nsString.h"
#include "nsITextServicesDocument.h"
#include "mozIPersonalDictionary.h"
#include "mozISpellCheckingEngine.h"
#include "nsClassHashtable.h"
#include "nsVoidArray.h"
#include "nsTArray.h"
#include "mozISpellI18NUtil.h"
+#include "nsCycleCollectionParticipant.h"
class mozSpellChecker : public nsISpellChecker
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_CLASS(mozSpellChecker)
mozSpellChecker();
virtual ~mozSpellChecker();
nsresult Init();
// nsISpellChecker
NS_IMETHOD SetDocument(nsITextServicesDocument *aDoc, PRBool aFromStartofDoc);
--- a/extensions/spellcheck/src/mozSpellI18NManager.cpp
+++ b/extensions/spellcheck/src/mozSpellI18NManager.cpp
@@ -35,17 +35,26 @@
*
* ***** END LICENSE BLOCK ***** */
#include "mozSpellI18NManager.h"
#include "mozEnglishWordUtils.h"
#include "mozGenericWordUtils.h"
#include "nsString.h"
-NS_IMPL_ISUPPORTS1(mozSpellI18NManager, mozISpellI18NManager)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(mozSpellI18NManager)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(mozSpellI18NManager)
+
+NS_INTERFACE_MAP_BEGIN(mozSpellI18NManager)
+ NS_INTERFACE_MAP_ENTRY(mozISpellI18NManager)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, mozISpellI18NManager)
+ NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(mozSpellI18NManager)
+NS_INTERFACE_MAP_END
+
+NS_IMPL_CYCLE_COLLECTION_0(mozSpellI18NManager)
mozSpellI18NManager::mozSpellI18NManager()
{
/* member initializers and constructor code */
}
mozSpellI18NManager::~mozSpellI18NManager()
{
--- a/extensions/spellcheck/src/mozSpellI18NManager.h
+++ b/extensions/spellcheck/src/mozSpellI18NManager.h
@@ -35,26 +35,28 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozSpellI18NManager_h__
#define mozSpellI18NManager_h__
#include "nsCOMPtr.h"
#include "mozISpellI18NManager.h"
+#include "nsCycleCollectionParticipant.h"
#define MOZ_SPELLI18NMANAGER_CONTRACTID "@mozilla.org/spellchecker/i18nmanager;1"
#define MOZ_SPELLI18NMANAGER_CID \
{ /* {AEB8936F-219C-4D3C-8385-D9382DAA551A} */ \
0xaeb8936f, 0x219c, 0x4d3c, \
{ 0x83, 0x85, 0xd9, 0x38, 0x2d, 0xaa, 0x55, 0x1a } }
class mozSpellI18NManager : public mozISpellI18NManager
{
public:
- NS_DECL_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_MOZISPELLI18NMANAGER
+ NS_DECL_CYCLE_COLLECTION_CLASS(mozSpellI18NManager)
mozSpellI18NManager();
virtual ~mozSpellI18NManager();
};
#endif
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -109,15 +109,17 @@ fix-win32-show-glyphs-clipping.patch: fi
native-clipping.patch: Add support for a native clipping api
quartz-is-clear.patch: Propagate the quartz is_clear flag.
cairo-qt-compile.patch: Fix compile error, return not reached, and clone_similar interface
==== pixman patches ====
+pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
+
pixman-rename-and-endian.patch: include cairo-platform.h for renaming of external symbols and endian macros
NOTE: we previously supported ARM assembler on MSVC, this has been removed because of the maintenance burden
==== disable printing patch ====
disable-printing.patch: allows us to use NS_PRINTING to disable printing.
--- a/gfx/cairo/libpixman/src/pixman-cpu.c
+++ b/gfx/cairo/libpixman/src/pixman-cpu.c
@@ -234,16 +234,54 @@ pixman_have_arm_neon (void)
static pixman_bool_t arm_has_v7 = FALSE;
static pixman_bool_t arm_has_v6 = FALSE;
static pixman_bool_t arm_has_vfp = FALSE;
static pixman_bool_t arm_has_neon = FALSE;
static pixman_bool_t arm_has_iwmmxt = FALSE;
static pixman_bool_t arm_tests_initialized = FALSE;
+#ifdef ANDROID
+
+/* on Android, we can't reliably access /proc/self/auxv,
+ * so instead read the text version in /proc/cpuinfo and
+ * parse that instead.
+ */
+
+static void
+pixman_arm_read_auxv()
+{
+ char buf[1024];
+ char* pos;
+ const char* ver_token = "CPU architecture: ";
+ FILE* f = fopen("/proc/cpuinfo", "r");
+ if (!f) {
+ arm_tests_initialized = TRUE;
+ return;
+ }
+
+ fread(buf, sizeof(char), 1024, f);
+ fclose(f);
+ pos = strstr(buf, ver_token);
+ if (pos) {
+ char vchar = *(pos + strlen(ver_token));
+ if (vchar >= '0' && vchar <= '9') {
+ int ver = vchar - '0';
+ arm_has_v7 = ver >= 7;
+ arm_has_v6 = ver >= 6;
+ }
+ }
+ arm_has_neon = strstr(buf, "neon") != NULL;
+ arm_has_vfp = strstr(buf, "vfp") != NULL;
+ arm_has_iwmmxt = strstr(buf, "iwmmxt") != NULL;
+ arm_tests_initialized = TRUE;
+}
+
+#else
+
static void
pixman_arm_read_auxv ()
{
int fd;
Elf32_auxv_t aux;
fd = open ("/proc/self/auxv", O_RDONLY);
if (fd >= 0)
@@ -275,16 +313,17 @@ pixman_arm_read_auxv ()
}
}
}
close (fd);
}
arm_tests_initialized = TRUE;
}
+#endif
#if defined(USE_ARM_SIMD)
pixman_bool_t
pixman_have_arm_simd (void)
{
if (!arm_tests_initialized)
pixman_arm_read_auxv ();
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/pixman-android-cpu-detect.patch
@@ -0,0 +1,29 @@
+diff --git a/gfx/cairo/libpixman/src/pixman-cpu.c b/gfx/cairo/libpixman/src/pixman-cpu.c
+--- a/gfx/cairo/libpixman/src/pixman-cpu.c
++++ b/gfx/cairo/libpixman/src/pixman-cpu.c
+@@ -257,19 +257,22 @@ pixman_arm_read_auxv()
+ arm_tests_initialized = TRUE;
+ return;
+ }
+
+ fread(buf, sizeof(char), 1024, f);
+ fclose(f);
+ pos = strstr(buf, ver_token);
+ if (pos) {
+- int ver = *(pos + strlen(ver_token)) - '0';
+- arm_has_v7 = ver >= 7;
+- arm_has_v6 = ver >= 6;
++ char vchar = *(pos + strlen(ver_token));
++ if (vchar >= '0' && vchar <= '9') {
++ int ver = vchar - '0';
++ arm_has_v7 = ver >= 7;
++ arm_has_v6 = ver >= 6;
++ }
+ }
+ arm_has_neon = strstr(buf, "neon") != NULL;
+ arm_has_vfp = strstr(buf, "vfp") != NULL;
+ arm_has_iwmmxt = strstr(buf, "iwmmxt") != NULL;
+ arm_tests_initialized = TRUE;
+ }
+
+ #else
--- a/gfx/src/nsColor.cpp
+++ b/gfx/src/nsColor.cpp
@@ -150,59 +150,87 @@ NS_GFX_(PRBool) NS_HexToRGB(const nsStri
// single digit to compute the new value.
r = (r << 4) | r;
g = (g << 4) | g;
b = (b << 4) | b;
}
NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
- if (nsnull != aResult) {
- *aResult = NS_RGB(r, g, b);
- }
+ *aResult = NS_RGB(r, g, b);
return PR_TRUE;
}
// Improperly formatted color value
return PR_FALSE;
}
-// compatible with legacy Nav behavior
+// This implements part of the algorithm for legacy behavior described in
+// http://www.whatwg.org/specs/web-apps/current-work/complete/common-microsyntaxes.html#rules-for-parsing-a-legacy-color-value
NS_GFX_(PRBool) NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
{
+ if (aColorSpec.EqualsLiteral("transparent")) {
+ return PR_FALSE;
+ }
+
int nameLen = aColorSpec.Length();
const PRUnichar* colorSpec = aColorSpec.get();
+ if (nameLen > 128) {
+ nameLen = 128;
+ }
+
if ('#' == colorSpec[0]) {
++colorSpec;
--nameLen;
}
- if (3 < nameLen) {
- // Convert the ascii to binary
- int dpc = (nameLen / 3) + (((nameLen % 3) != 0) ? 1 : 0);
- if (4 < dpc) {
- dpc = 4;
- }
+ // digits per component
+ int dpc = (nameLen + 2) / 3;
+ int newdpc = dpc;
+
+ // Use only the rightmost 8 characters of each component.
+ if (newdpc > 8) {
+ nameLen -= newdpc - 8;
+ colorSpec += newdpc - 8;
+ newdpc = 8;
+ }
- // Translate components from hex to binary
- int r = ComponentValue(colorSpec, nameLen, 0, dpc);
- int g = ComponentValue(colorSpec, nameLen, 1, dpc);
- int b = ComponentValue(colorSpec, nameLen, 2, dpc);
- NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
- NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
- NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
- if (nsnull != aResult) {
- *aResult = NS_RGB(r, g, b);
+ // And then keep trimming characters at the left until we'd trim one
+ // that would leave a nonzero value, but not past 2 characters per
+ // component.
+ while (newdpc > 2) {
+ PRBool haveNonzero = PR_FALSE;
+ for (int c = 0; c < 3; ++c) {
+ NS_ABORT_IF_FALSE(c * dpc < nameLen,
+ "should not pass end of string while newdpc > 2");
+ PRUnichar ch = colorSpec[c * dpc];
+ if (('1' <= ch && ch <= '9') ||
+ ('A' <= ch && ch <= 'F') ||
+ ('a' <= ch && ch <= 'f')) {
+ haveNonzero = PR_TRUE;
+ break;
+ }
}
+ if (haveNonzero) {
+ break;
+ }
+ --newdpc;
+ --nameLen;
+ ++colorSpec;
}
- else {
- if (nsnull != aResult) {
- *aResult = NS_RGB(0, 0, 0);
- }
- }
+
+ // Translate components from hex to binary
+ int r = ComponentValue(colorSpec, nameLen, 0, dpc);
+ int g = ComponentValue(colorSpec, nameLen, 1, dpc);
+ int b = ComponentValue(colorSpec, nameLen, 2, dpc);
+ NS_ASSERTION((r >= 0) && (r <= 255), "bad r");
+ NS_ASSERTION((g >= 0) && (g <= 255), "bad g");
+ NS_ASSERTION((b >= 0) && (b <= 255), "bad b");
+
+ *aResult = NS_RGB(r, g, b);
return PR_TRUE;
}
NS_GFX_(PRBool) NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
{
if (!gColorTable) return PR_FALSE;
PRInt32 id = gColorTable->Lookup(aColorName);
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -1659,17 +1659,16 @@ def _generateCxxUnion(ud):
refClsType = Type(ud.name, ref=1)
typetype = Type('Type')
valuetype = Type('Value')
mtypevar = ExprVar('mType')
mvaluevar = ExprVar('mValue')
maybedtorvar = ExprVar('MaybeDestroy')
assertsanityvar = ExprVar('AssertSanity')
tnonevar = ExprVar('T__None')
- tfirstvar = ExprVar('T__First')
tlastvar = ExprVar('T__Last')
def callAssertSanity(uvar=None, expectTypeVar=None):
func = assertsanityvar
args = [ ]
if uvar is not None:
func = ExprSelect(uvar, '.', assertsanityvar.name)
if expectTypeVar is not None:
@@ -1695,17 +1694,16 @@ def _generateCxxUnion(ud):
# the |Type| enum, used to switch on the discunion's real type
cls.addstmt(Label.PUBLIC)
typeenum = TypeEnum(typetype.name)
typeenum.addId(tnonevar.name, 0)
firstid = ud.components[0].enum()
typeenum.addId(firstid, 1)
for c in ud.components[1:]:
typeenum.addId(c.enum())
- typeenum.addId(tfirstvar.name, firstid)
typeenum.addId(tlastvar.name, ud.components[-1].enum())
cls.addstmts([ StmtDecl(Decl(typeenum,'')),
Whitespace.NL ])
cls.addstmt(Label.PRIVATE)
cls.addstmts(
usingTypedefs
# hacky typedef's that allow placement dtors of builtins
@@ -1769,17 +1767,17 @@ def _generateCxxUnion(ud):
])
cls.addstmts([ maybedtor, Whitespace.NL ])
# add helper methods that ensure the discunion has a
# valid type
sanity = MethodDefn(MethodDecl(
assertsanityvar.name, ret=Type.VOID, const=1, force_inline=1))
sanity.addstmts([
- _abortIfFalse(ExprBinary(tfirstvar, '<=', mtypevar),
+ _abortIfFalse(ExprBinary(tnonevar, '<=', mtypevar),
'invalid type tag'),
_abortIfFalse(ExprBinary(mtypevar, '<=', tlastvar),
'invalid type tag') ])
cls.addstmt(sanity)
atypevar = ExprVar('aType')
sanity2 = MethodDefn(
MethodDecl(assertsanityvar.name,
@@ -1822,16 +1820,18 @@ def _generateCxxUnion(ud):
copyswitch.addcase(
CaseLabel(c.enum()),
StmtBlock([
StmtExpr(c.callCtor(
ExprCall(ExprSelect(othervar,
'.', c.getConstTypeName())))),
StmtBreak()
]))
+ copyswitch.addcase(CaseLabel(tnonevar.name),
+ StmtBlock([ StmtBreak() ]))
copyswitch.addcase(
DefaultLabel(),
StmtBlock([ _runtimeAbort('unreached'), StmtReturn() ]))
copyctor.addstmts([
StmtExpr(callAssertSanity(uvar=othervar)),
copyswitch,
StmtExpr(ExprAssn(mtypevar, othertype))
])
@@ -1875,16 +1875,19 @@ def _generateCxxUnion(ud):
case = StmtBlock()
case.addstmts([
maybeReconstruct(c, rhstypevar),
StmtExpr(c.callOperatorEq(
ExprCall(ExprSelect(rhsvar, '.', c.getConstTypeName())))),
StmtBreak()
])
opeqswitch.addcase(CaseLabel(c.enum()), case)
+ opeqswitch.addcase(CaseLabel(tnonevar.name),
+ StmtBlock([ StmtExpr(callMaybeDestroy(rhstypevar)),
+ StmtBreak() ]))
opeqswitch.addcase(
DefaultLabel(),
StmtBlock([ _runtimeAbort('unreached'), StmtBreak() ]))
opeq.addstmts([
StmtExpr(callAssertSanity(uvar=rhsvar)),
StmtDecl(Decl(typetype, rhstypevar.name), init=ud.callType(rhsvar)),
opeqswitch,
StmtExpr(ExprAssn(mtypevar, rhstypevar)),
--- a/ipc/ipdl/test/cxx/PTestDataStructures.ipdl
+++ b/ipc/ipdl/test/cxx/PTestDataStructures.ipdl
@@ -1,10 +1,12 @@
include protocol PTestDataStructuresSub;
+using mozilla::null_t;
+
namespace mozilla {
namespace _foo {
union IntDouble {
int;
double;
};
@@ -62,16 +64,33 @@ union WithStructs {
struct WithUnions {
int i;
int[] ai;
PTestDataStructuresSub[] ap;
Actors[] aa;
Unions[] au;
};
+struct CommonAttrs { bool dummy; };
+struct FooAttrs { int dummy; };
+struct BarAttrs { float dummy; };
+union SpecificAttrs {
+ FooAttrs;
+ BarAttrs;
+};
+struct Attrs {
+ CommonAttrs common;
+ SpecificAttrs specific;
+};
+struct SetAttrs {
+ PTestDataStructuresSub x;
+ Attrs attrs;
+};
+union Op { null_t; SetAttrs; };
+
} // namespace _foo
} // namespace mozilla
namespace mozilla {
namespace _ipdltest {
sync protocol PTestDataStructures {
manages PTestDataStructuresSub;
@@ -151,35 +170,38 @@ parent:
WithStructs o2,
WithStructs o3,
WithStructs o4,
WithStructs o5);
sync Test16(WithUnions i)
returns (WithUnions o);
+ sync Test17(Op[] ops);
+
state START:
send Start goto TEST1;
state TEST1: recv Test1 goto TEST2;
state TEST2: recv Test2 goto TEST3;
state TEST3: recv Test3 goto TEST4;
state TEST4: recv Test4 goto TEST5;
state TEST5: recv Test5 goto TEST6;
state TEST6: recv Test6 goto TEST7;
state TEST7: recv Test7 goto TEST8;
state TEST8: recv Test8 goto TEST9;
state TEST9: recv Test9 goto TEST10;
state TEST10: recv Test10 goto TEST11;
state TEST11: recv Test11 goto TEST12;
-state TEST12: recv Test11 goto TEST13;
-state TEST13: recv Test11 goto TEST14;
-state TEST14: recv Test11 goto TEST15;
-state TEST15: recv Test11 goto TEST16;
-state TEST16: recv Test11 goto DEAD;
+state TEST12: recv Test12 goto TEST13;
+state TEST13: recv Test13 goto TEST14;
+state TEST14: recv Test14 goto TEST15;
+state TEST15: recv Test15 goto TEST16;
+state TEST16: recv Test16 goto TEST17;
+state TEST17: recv Test17 goto DEAD;
state DEAD:
recv __delete__;
};
} // namespace _ipdltest
} // namespace mozilla
--- a/ipc/ipdl/test/cxx/TestDataStructures.cpp
+++ b/ipc/ipdl/test/cxx/TestDataStructures.cpp
@@ -412,16 +412,23 @@ bool TestDataStructuresParent::RecvTest1
iau[3].get_ArrayOfActors()[0]
.get_ArrayOfPTestDataStructuresSubParent());
*o = i;
return true;
}
+bool TestDataStructuresParent::RecvTest17(const nsTArray<Op>& sa)
+{
+ test_assert(sa.Length() == 1 && Op::TSetAttrs == sa[0].type(),
+ "wrong value");
+ return true;
+}
+
//-----------------------------------------------------------------------------
// child
TestDataStructuresChild::TestDataStructuresChild()
{
MOZ_COUNT_CTOR(TestDataStructuresChild);
}
@@ -446,16 +453,17 @@ TestDataStructuresChild::RecvStart()
Test9();
Test10();
Test11();
Test12();
Test13();
Test14();
Test15();
Test16();
+ Test17();
for (uint32 i = 0; i < nactors; ++i)
if (!PTestDataStructuresSubChild::Send__delete__(mKids[i]))
fail("can't send dtor");
Close();
return true;
@@ -868,10 +876,26 @@ TestDataStructuresChild::Test16()
mKids);
assert_arrays_equal(oau[3].get_ArrayOfActors()[0]
.get_ArrayOfPTestDataStructuresSubChild(),
mKids);
printf(" passed %s\n", __FUNCTION__);
}
+void
+TestDataStructuresChild::Test17()
+{
+ Attrs attrs;
+ attrs.common() = CommonAttrs(true);
+ attrs.specific() = BarAttrs(1.0f);
+
+ nsTArray<Op> ops;
+ ops.AppendElement(SetAttrs(NULL, mKids[0], attrs));
+
+ if (!SendTest17(ops))
+ fail("sending Test17");
+
+ printf(" passed %s\n", __FUNCTION__);
+}
+
} // namespace _ipdltest
} // namespace mozilla
--- a/ipc/ipdl/test/cxx/TestDataStructures.h
+++ b/ipc/ipdl/test/cxx/TestDataStructures.h
@@ -151,16 +151,19 @@ protected:
WithStructs* o5);
NS_OVERRIDE
virtual bool RecvTest16(
const WithUnions& i,
WithUnions* o);
NS_OVERRIDE
+ virtual bool RecvTest17(const nsTArray<Op>& sa);
+
+ NS_OVERRIDE
virtual void ActorDestroy(ActorDestroyReason why)
{
if (NormalShutdown != why)
fail("unexpected destruction!");
passed("ok");
QuitParent();
}
@@ -215,16 +218,17 @@ private:
void Test9();
void Test10();
void Test11();
void Test12();
void Test13();
void Test14();
void Test15();
void Test16();
+ void Test17();
nsTArray<PTestDataStructuresSubChild*> mKids;
};
} // namespace _ipdltest
} // namespace mozilla
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -197,38 +197,37 @@ case "$target" in
if test -z "$CXX"; then CXX=g++-4.2; fi
;;
esac
fi
COMPILE_ENVIRONMENT=1
MOZ_ARG_ENABLE_BOOL(compile-environment,
[ --disable-compile-environment
- Disable compiler/library checks.],
+ Disable compiler/library checks.],
COMPILE_ENVIRONMENT=1,
COMPILE_ENVIRONMENT= )
dnl ========================================================
dnl = Android uses a very custom (hacky) toolchain; we need to do this
dnl = here, so that the compiler checks can succeed
dnl ========================================================
MOZ_ARG_WITH_STRING(android-ndk,
-[ --with-android-ndk=DIR
- location where the Android NDK can be found],
+[ --with-android-ndk=DIR location where the Android NDK can be found],
android_ndk=$withval)
MOZ_ARG_WITH_STRING(android-toolchain,
[ --with-android-toolchain=DIR
- location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
+ location of the android toolchain, default NDK/build/prebuilt/HOST/arm-eabi-4.4.0],
android_toolchain=$withval)
MOZ_ARG_WITH_STRING(android-platform,
[ --with-android-platform=DIR
- location of platform dir, default NDK/build/platforms/android-5/arch-arm],
+ location of platform dir, default NDK/build/platforms/android-5/arch-arm],
android_platform=$withval)
if test "$target" = "arm-android-eabi" ; then
if test -z "$android_ndk" ; then
AC_MSG_ERROR([You must specify --with-android-ndk=/path/to/ndk when targeting Android.])
fi
if test -z "$android_toolchain" ; then
@@ -355,17 +354,17 @@ if test "$target" != "$host"; then
CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk $CXXFLAGS"
;;
esac
case "$target" in
*symbian*)
AC_ARG_WITH(symbian-sdk,
[ --with-symbian-sdk=SYMBIAN_SDK_DIR
- The path to the Symbian SDK],
+ The path to the Symbian SDK],
SYMBIAN_SDK_DIR=$withval)
OS_EXE_CFLAGS="$OS_EXE_CFLAGS -D__EXE__"
CFLAGS="-MD -nostdinc"
SYMBIAN_SYS_INCLUDE="-I$SYMBIAN_SDK_DIR/Epoc32/include -I$SYMBIAN_SDK_DIR/Epoc32/include/variant -I$SYMBIAN_SDK_DIR/Epoc32/include/stdapis"
case "$target" in
*-symbianelf)
@@ -883,17 +882,17 @@ esac
AC_SUBST(MACOSX_DEPLOYMENT_TARGET)
dnl ========================================================
dnl = Mac OS X SDK support
dnl ========================================================
MACOS_SDK_DIR=
NEXT_ROOT=
MOZ_ARG_WITH_STRING(macos-sdk,
-[ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)],
+[ --with-macos-sdk=dir Location of platform SDK to use (Mac OS X only)],
MACOS_SDK_DIR=$withval)
dnl MACOS_SDK_DIR will be set to the SDK location whenever one is in use.
dnl NEXT_ROOT will be set and exported only if it's needed.
AC_SUBST(MACOS_SDK_DIR)
AC_SUBST(NEXT_ROOT)
if test "$MACOS_SDK_DIR"; then
@@ -1988,17 +1987,18 @@ ia64*-hpux*)
MOZ_ENABLE_POSTSCRIPT=
MOZ_USER_DIR="Mozilla"
dnl Default to Windows Mobile components enabled
WINCE_WINDOWS_MOBILE=1
MOZ_ARG_DISABLE_BOOL(windows-mobile-components,
[ --disable-windows-mobile-components
- Disable Windows Mobile specific components from CE build],
+ Disable Windows Mobile specific components from
+ CE build],
WINCE_WINDOWS_MOBILE=,
WINCE_WINDOWS_MOBILE=1)
if test "$WINCE_WINDOWS_MOBILE"; then
AC_DEFINE(WINCE_WINDOWS_MOBILE)
fi
;;
@@ -2594,17 +2594,17 @@ arm*-*)
;;
sparc*-*)
ENABLE_TRACEJIT=1
NANOJIT_ARCH=Sparc
;;
esac
MOZ_ARG_DISABLE_BOOL(tracejit,
-[ --disable-tracejit Disable tracing JIT support],
+[ --disable-tracejit Disable tracing JIT support],
ENABLE_TRACEJIT=)
if test "$ENABLE_TRACEJIT"; then
AC_DEFINE(FEATURE_NANOJIT)
AC_DEFINE(JS_TRACER)
case "$target" in
@@ -3969,17 +3969,18 @@ MOZ_ARG_WITH_BOOL(system-nspr,
Use the 'nspr-config' script in the current path,
or look for the script in the directories given with
--with-nspr-exec-prefix or --with-nspr-prefix.
(Those flags are only checked if you specify
--with-system-nspr.)],
_USE_SYSTEM_NSPR=1 )
MOZ_ARG_WITH_STRING(nspr-cflags,
-[ --with-nspr-cflags=FLAGS Pass FLAGS to CC when building code that uses NSPR.
+[ --with-nspr-cflags=FLAGS
+ Pass FLAGS to CC when building code that uses NSPR.
Use this when there's no accurate nspr-config
script available. This is the case when building
SpiderMonkey as part of the Mozilla tree: the
top-level configure script computes NSPR flags
that accomodate the quirks of that environment.],
NSPR_CFLAGS=$withval)
MOZ_ARG_WITH_STRING(nspr-libs,
[ --with-nspr-libs=LIBS Pass LIBS to LD when linking code that uses NSPR.
@@ -4017,17 +4018,17 @@ if test -n "$MOZ_NATIVE_NSPR"; then
CFLAGS=$_SAVE_CFLAGS
fi
dnl ========================================================
dnl Use ARM userspace kernel helpers; tell NSPR to enable
dnl their usage and use them in spidermonkey.
dnl ========================================================
MOZ_ARG_WITH_BOOL(arm-kuser,
-[ --with-arm-kuser Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
+[ --with-arm-kuser Use kuser helpers (Linux/ARM only -- requires kernel 2.6.13 or later)],
USE_ARM_KUSER=1,
USE_ARM_KUSER=)
if test -n "$USE_ARM_KUSER"; then
AC_DEFINE(USE_ARM_KUSER)
fi
dnl ========================================================
dnl =
@@ -4048,17 +4049,17 @@ dnl ====================================
MOZ_ARG_HEADER(Components and Features)
dnl ========================================================
dnl ========================================================
dnl = Enable building the Thumb2 instruction set
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(thumb2,
- [ --enable-thumb2 Enable Thumb2 instruction set],
+ [ --enable-thumb2 Enable Thumb2 instruction set],
MOZ_THUMB2=1,)
if test -n "$MOZ_THUMB2"; then
case "$target_cpu" in
arm*)
if test "$GNU_CC"; then
CFLAGS="$CFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
CXXFLAGS="$CXXFLAGS -march=armv7-a -mthumb -Wa, -march=armv7-a -Wa, -mthumb"
@@ -4229,18 +4230,18 @@ MOZ_ARG_ENABLE_STRING(debugger-info-modu
AC_MSG_WARN([--enable-debugger-info-modules is deprecated, use --enable-debug-symbols instead])
MOZ_DEBUG_SYMBOLS=1
fi ])
dnl ========================================================
dnl = Enable generation of debug symbols
dnl ========================================================
MOZ_ARG_ENABLE_STRING(debug-symbols,
-[ --enable-debug-symbols[=DBG] Enable debugging symbols
- (using compiler flags DBG)],
+[ --enable-debug-symbols[=DBG]
+ Enable debugging symbols (using compiler flags DBG)],
[ if test "$enableval" != "no"; then
MOZ_DEBUG_SYMBOLS=1
if test -n "$enableval" -a "$enableval" != "yes"; then
if test -z "$_MOZ_DEBUG_FLAGS_SET"; then
MOZ_DEBUG_FLAGS=`echo $enableval | sed -e 's|\\\ | |g'`
else
AC_MSG_ERROR([--enable-debug-symbols flags cannot be used with --enable-debug flags])
fi
@@ -4251,17 +4252,17 @@ if test -n "$MOZ_DEBUG" -o -n "$MOZ_DEBU
AC_DEFINE(MOZ_DEBUG_SYMBOLS)
export MOZ_DEBUG_SYMBOLS
fi
dnl ========================================================
dnl Enable Narcissus
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(narcissus,
-[ --enable-narcissus Build with Narcissus code enabled],
+[ --enable-narcissus Build with Narcissus code enabled],
NARCISSUS=1,
NARCISSUS= )
if test -n "$NARCISSUS"; then
AC_DEFINE(NARCISSUS)
fi
dnl ========================================================
dnl = Enable trace malloc
@@ -4408,17 +4409,17 @@ if test -n "$MOZ_TRACEVIS"; then
AC_MSG_ERROR([--enable-tracevis is incompatible with --disable-tracejit])
fi
fi
dnl ========================================================
dnl = Use GCTimer
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(gctimer,
-[ --enable-gctimer Enable GC timer (default=no)],
+[ --enable-gctimer Enable GC timer (default=no)],
MOZ_GCTIMER=1,
MOZ_GCTIMER= )
if test -n "$MOZ_GCTIMER"; then
AC_DEFINE(MOZ_GCTIMER)
fi
dnl ========================================================
dnl = Use Valgrind
@@ -4477,30 +4478,30 @@ MOZ_ARG_ENABLE_BOOL(vtune,
if test -n "$MOZ_VTUNE"; then
AC_DEFINE(MOZ_VTUNE)
fi
dnl ========================================================
dnl Zealous GC
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(gczeal,
-[ --enable-gczeal Enable zealous GCing],
+[ --enable-gczeal Enable zealous GCing],
JS_GC_ZEAL=1,
JS_GC_ZEAL= )
if test -n "$JS_GC_ZEAL"; then
AC_DEFINE(JS_GC_ZEAL)
fi
dnl ========================================================
dnl = Enable static checking using gcc-dehydra
dnl ========================================================
MOZ_ARG_WITH_STRING(static-checking,
[ --with-static-checking=path/to/gcc_dehydra.so
- Enable static checking of code using GCC-dehydra],
+ Enable static checking of code using GCC-dehydra],
DEHYDRA_PATH=$withval,
DEHYDRA_PATH= )
if test -n "$DEHYDRA_PATH"; then
if test ! -f "$DEHYDRA_PATH"; then
AC_MSG_ERROR([The dehydra plugin is not at the specified path.])
fi
AC_DEFINE(NS_STATIC_CHECKING)
@@ -4542,17 +4543,17 @@ MOZ_ARG_ENABLE_BOOL(timeline,
if test -n "$MOZ_TIMELINE"; then
AC_DEFINE(MOZ_TIMELINE)
fi
dnl ========================================================
dnl = Support for Quantify (Windows)
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(quantify,
-[ --enable-quantify Enable Quantify support (Windows only) ],
+[ --enable-quantify Enable Quantify support (Windows only) ],
MOZ_QUANTIFY=1,
MOZ_QUANTIFY= )
dnl ========================================================
dnl = Support for demangling undefined symbols
dnl ========================================================
if test -z "$SKIP_LIBRARY_CHECKS"; then
AC_LANG_SAVE
@@ -4640,17 +4641,17 @@ dnl Profile guided optimization
dnl ========================================================
dnl Test for profiling options
dnl Under gcc 3.3, use -fprofile-arcs/-fbranch-probabilities
dnl Under gcc 3.4+, use -fprofile-generate/-fprofile-use
dnl Provide a switch to disable PGO even when called via profiledbuild.
MOZ_ARG_DISABLE_BOOL(profile-guided-optimization,