mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
about:config - merge with trunk
This commit is contained in:
commit
2895410af9
@ -91,14 +91,6 @@ nsAccDocManager::FindAccessibleInCache(nsINode* aNode) const
|
||||
return arg.mAccessible;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocument *aDocument)
|
||||
{
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(container);
|
||||
ShutdownDocAccessiblesInTree(treeItem, aDocument);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager protected
|
||||
@ -132,21 +124,6 @@ nsAccDocManager::Shutdown()
|
||||
ClearDocCache();
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::ShutdownDocAccessible(nsIDocument *aDocument)
|
||||
{
|
||||
nsDocAccessible* docAccessible = mDocAccessibleCache.GetWeak(aDocument);
|
||||
if (!docAccessible)
|
||||
return;
|
||||
|
||||
// We're allowed to not remove listeners when accessible document is shutdown
|
||||
// since we don't keep strong reference on chrome event target and listeners
|
||||
// are removed automatically when chrome event target goes away.
|
||||
|
||||
docAccessible->Shutdown();
|
||||
mDocAccessibleCache.Remove(aDocument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
|
||||
@ -316,7 +293,14 @@ nsAccDocManager::HandleEvent(nsIDOMEvent *aEvent)
|
||||
return NS_OK;
|
||||
|
||||
// Shutdown this one and sub document accessibles.
|
||||
ShutdownDocAccessiblesInTree(document);
|
||||
|
||||
// We're allowed to not remove listeners when accessible document is
|
||||
// shutdown since we don't keep strong reference on chrome event target and
|
||||
// listeners are removed automatically when chrome event target goes away.
|
||||
nsDocAccessible* docAccessible = mDocAccessibleCache.GetWeak(document);
|
||||
if (docAccessible)
|
||||
docAccessible->Shutdown();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -500,35 +484,6 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
|
||||
return docAcc;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccDocManager::ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
|
||||
nsIDocument *aDocument)
|
||||
{
|
||||
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aTreeItem));
|
||||
|
||||
if (treeNode) {
|
||||
PRInt32 subDocumentsCount = 0;
|
||||
treeNode->GetChildCount(&subDocumentsCount);
|
||||
for (PRInt32 idx = 0; idx < subDocumentsCount; idx++) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItemChild;
|
||||
treeNode->GetChildAt(idx, getter_AddRefs(treeItemChild));
|
||||
NS_ASSERTION(treeItemChild, "No tree item when there should be");
|
||||
if (!treeItemChild)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(treeItemChild));
|
||||
nsCOMPtr<nsIContentViewer> contentViewer;
|
||||
docShell->GetContentViewer(getter_AddRefs(contentViewer));
|
||||
if (!contentViewer)
|
||||
continue;
|
||||
|
||||
ShutdownDocAccessiblesInTree(treeItemChild, contentViewer->GetDocument());
|
||||
}
|
||||
}
|
||||
|
||||
ShutdownDocAccessible(aDocument);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccDocManager static
|
||||
|
||||
|
@ -75,13 +75,6 @@ public:
|
||||
*/
|
||||
nsAccessible* FindAccessibleInCache(nsINode* aNode) const;
|
||||
|
||||
/**
|
||||
* Shutdown document accessibles in the tree starting from the given one.
|
||||
*
|
||||
* @param aDocument [in] the DOM document of start document accessible
|
||||
*/
|
||||
void ShutdownDocAccessiblesInTree(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Return document accessible from the cache. Convenient method for testing.
|
||||
*/
|
||||
@ -90,6 +83,14 @@ public:
|
||||
return mDocAccessibleCache.GetWeak(aDocument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by document accessible when it gets shutdown.
|
||||
*/
|
||||
inline void NotifyOfDocumentShutdown(nsIDocument* aDocument)
|
||||
{
|
||||
mDocAccessibleCache.Remove(aDocument);
|
||||
}
|
||||
|
||||
protected:
|
||||
nsAccDocManager() { };
|
||||
|
||||
@ -103,11 +104,6 @@ protected:
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* Shutdown the document accessible.
|
||||
*/
|
||||
void ShutdownDocAccessible(nsIDocument* aDocument);
|
||||
|
||||
private:
|
||||
nsAccDocManager(const nsAccDocManager&);
|
||||
nsAccDocManager& operator =(const nsAccDocManager&);
|
||||
@ -156,12 +152,6 @@ private:
|
||||
*/
|
||||
nsDocAccessible *CreateDocOrRootAccessible(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Shutdown document accessibles in the tree starting from given tree item.
|
||||
*/
|
||||
void ShutdownDocAccessiblesInTree(nsIDocShellTreeItem *aTreeItem,
|
||||
nsIDocument *aDocument);
|
||||
|
||||
typedef nsRefPtrHashtable<nsPtrHashKey<const nsIDocument>, nsDocAccessible>
|
||||
nsDocAccessibleHashtable;
|
||||
|
||||
|
@ -382,7 +382,8 @@ nsAccessNode::ScrollTo(PRUint32 aScrollType)
|
||||
|
||||
PRInt16 vPercent, hPercent;
|
||||
nsCoreUtils::ConvertScrollTypeToPercents(aScrollType, &vPercent, &hPercent);
|
||||
return shell->ScrollContentIntoView(content, vPercent, hPercent);
|
||||
return shell->ScrollContentIntoView(content, vPercent, hPercent,
|
||||
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -543,7 +543,10 @@ nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
|
||||
return;
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
|
||||
ShutdownDocAccessible(doc);
|
||||
|
||||
nsDocAccessible* docAccessible = GetDocAccessibleFromCache(doc);
|
||||
if (docAccessible)
|
||||
docAccessible->Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2368,7 +2368,8 @@ nsAccessible::DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex)
|
||||
|
||||
// Scroll into view.
|
||||
presShell->ScrollContentIntoView(aContent, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
|
||||
|
||||
// Fire mouse down and mouse up events.
|
||||
PRBool res = nsCoreUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
|
||||
@ -2766,6 +2767,13 @@ nsAccessible::RemoveChild(nsAccessible* aChild)
|
||||
if (aChild->mParent != this || aChild->mIndexInParent == -1)
|
||||
return PR_FALSE;
|
||||
|
||||
if (aChild->mIndexInParent >= mChildren.Length() ||
|
||||
mChildren[aChild->mIndexInParent] != aChild) {
|
||||
NS_ERROR("Child is bound to parent but parent hasn't this child at its index!");
|
||||
aChild->UnbindFromParent();
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
for (PRUint32 idx = aChild->mIndexInParent + 1; idx < mChildren.Length(); idx++)
|
||||
mChildren[idx]->mIndexInParent--;
|
||||
|
||||
|
@ -675,6 +675,10 @@ nsDocAccessible::Shutdown()
|
||||
mParent->RemoveChild(this);
|
||||
}
|
||||
|
||||
PRUint32 childDocCount = mChildDocuments.Length();
|
||||
for (PRUint32 idx = 0; idx < childDocCount; idx++)
|
||||
mChildDocuments[idx]->Shutdown();
|
||||
|
||||
mChildDocuments.Clear();
|
||||
|
||||
mWeakShell = nsnull; // Avoid reentrancy
|
||||
@ -686,6 +690,8 @@ nsDocAccessible::Shutdown()
|
||||
mDocument = nsnull;
|
||||
|
||||
nsHyperTextAccessibleWrap::Shutdown();
|
||||
|
||||
GetAccService()->NotifyOfDocumentShutdown(kungFuDeathGripDoc);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
|
@ -169,7 +169,7 @@ nsOuterDocAccessible::Shutdown()
|
||||
if (childAcc) {
|
||||
NS_LOG_ACCDOCDESTROY("outerdoc's child document shutdown",
|
||||
childAcc->GetDocumentNode())
|
||||
GetAccService()->ShutdownDocAccessiblesInTree(childAcc->GetDocumentNode());
|
||||
childAcc->Shutdown();
|
||||
}
|
||||
|
||||
nsAccessibleWrap::Shutdown();
|
||||
|
@ -1538,7 +1538,7 @@ nsHyperTextAccessible::SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
// XXX I'm not sure this can do synchronous scrolling. If the last param is
|
||||
// set to true, this calling might flush the pending reflow. See bug 418470.
|
||||
selCon->ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL,
|
||||
nsISelectionController::SELECTION_FOCUS_REGION, PR_FALSE);
|
||||
nsISelectionController::SELECTION_FOCUS_REGION, 0);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -972,8 +972,9 @@ var PlacesStarButton = {
|
||||
this.updateState();
|
||||
this._batching = false;
|
||||
},
|
||||
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolder, aIndex, aItemType) {
|
||||
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolder, aIndex, aItemType,
|
||||
aURI) {
|
||||
if (!this._batching && !this._starred)
|
||||
this.updateState();
|
||||
},
|
||||
|
@ -819,8 +819,7 @@ const gFormSubmitObserver = {
|
||||
return;
|
||||
}
|
||||
|
||||
// Limit the message to 256 characters.
|
||||
this.panel.firstChild.textContent = element.validationMessage.substring(0, 256);
|
||||
this.panel.firstChild.textContent = element.validationMessage;
|
||||
|
||||
element.focus();
|
||||
|
||||
@ -3986,6 +3985,27 @@ var XULBrowserWindow = {
|
||||
encodeURIComponent);
|
||||
gURLBar.setOverLink(link);
|
||||
},
|
||||
|
||||
// Called before links are navigated to to allow us to retarget them if needed.
|
||||
onBeforeLinkTraversal: function(originalTarget, linkURI, linkNode, isAppTab) {
|
||||
// Don't modify non-default targets or targets that aren't in top-level app
|
||||
// tab docshells (isAppTab will be false for app tab subframes).
|
||||
if (originalTarget != "" || !isAppTab)
|
||||
return originalTarget;
|
||||
|
||||
let docURI = linkNode.ownerDocument.documentURIObject;
|
||||
try {
|
||||
let docURIDomain = Services.eTLD.getBaseDomain(docURI, 0);
|
||||
let linkURIDomain = Services.eTLD.getBaseDomain(linkURI, 0);
|
||||
// External links from within app tabs should always open in new tabs
|
||||
// instead of replacing the app tab's page (Bug 575561)
|
||||
if (docURIDomain != linkURIDomain)
|
||||
return "_blank";
|
||||
} catch(e) {
|
||||
// If getBaseDomain fails, we return originalTarget below.
|
||||
}
|
||||
return originalTarget;
|
||||
},
|
||||
|
||||
onLinkIconAvailable: function (aIconURL) {
|
||||
if (gProxyFavIcon && gBrowser.userTypedValue === null)
|
||||
@ -7487,6 +7507,7 @@ let gPrivateBrowsingUI = {
|
||||
// temporary fix until bug 463607 is fixed
|
||||
document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
|
||||
|
||||
let docElement = document.documentElement;
|
||||
if (this._privateBrowsingService.autoStarted) {
|
||||
// Disable the menu item in auto-start mode
|
||||
document.getElementById("privateBrowsingItem")
|
||||
@ -7497,15 +7518,16 @@ let gPrivateBrowsingUI = {
|
||||
#endif
|
||||
document.getElementById("Tools:PrivateBrowsing")
|
||||
.setAttribute("disabled", "true");
|
||||
if (window.location.href == getBrowserURL())
|
||||
docElement.setAttribute("privatebrowsingmode", "permanent");
|
||||
}
|
||||
else if (window.location.href == getBrowserURL()) {
|
||||
// Adjust the window's title
|
||||
let docElement = document.documentElement;
|
||||
docElement.setAttribute("title",
|
||||
docElement.getAttribute("title_privatebrowsing"));
|
||||
docElement.setAttribute("titlemodifier",
|
||||
docElement.getAttribute("titlemodifier_privatebrowsing"));
|
||||
docElement.setAttribute("browsingmode", "private");
|
||||
docElement.setAttribute("privatebrowsingmode", "temporary");
|
||||
gBrowser.updateTitlebar();
|
||||
}
|
||||
|
||||
@ -7552,7 +7574,7 @@ let gPrivateBrowsingUI = {
|
||||
docElement.getAttribute("title_normal"));
|
||||
docElement.setAttribute("titlemodifier",
|
||||
docElement.getAttribute("titlemodifier_normal"));
|
||||
docElement.setAttribute("browsingmode", "normal");
|
||||
docElement.removeAttribute("privatebrowsingmode");
|
||||
}
|
||||
|
||||
// Enable the menu item in after exiting the auto-start mode
|
||||
|
@ -826,12 +826,7 @@
|
||||
#ifdef WINCE
|
||||
defaulticonsize="small" iconsize="small"
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
tabsontop="true"
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
tabsontop="true"
|
||||
#endif
|
||||
persist="tabsontop">
|
||||
<!-- Menu -->
|
||||
<toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
|
||||
@ -1014,7 +1009,9 @@
|
||||
key="manBookmarkKb"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="BMB_bookmarkThisPage"
|
||||
#ifndef XP_MACOSX
|
||||
class="menuitem-iconic"
|
||||
#endif
|
||||
label="&bookmarkThisPageCmd.label;"
|
||||
command="Browser:AddBookmarkAs"
|
||||
key="addBookmarkAsKb"/>
|
||||
|
@ -958,14 +958,17 @@ nsContextMenu.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
// in case we need to prompt the user for authentication
|
||||
function callbacks() {}
|
||||
callbacks.prototype = {
|
||||
getInterface: function sLA_callbacks_getInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) {
|
||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||
getService(Ci.nsIPromptFactory);
|
||||
return ww.getPrompt(doc.defaultView, aIID);
|
||||
// If the channel demands authentication prompt, we must cancel it
|
||||
// because the save-as-timer would expire and cancel the channel
|
||||
// before we get credentials from user. Both authentication dialog
|
||||
// and save as dialog would appear on the screen as we fall back to
|
||||
// the old fashioned way after the timeout.
|
||||
timer.cancel();
|
||||
channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT);
|
||||
}
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
@ -191,6 +191,8 @@
|
||||
this.tabContainer._positionPinnedTabs();
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
this.getBrowserForTab(aTab).docShell.isAppTab = true;
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TabPinned", true, false);
|
||||
aTab.dispatchEvent(event);
|
||||
@ -210,6 +212,8 @@
|
||||
this.tabContainer._positionPinnedTabs();
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
this.getBrowserForTab(aTab).docShell.isAppTab = false;
|
||||
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("TabUnpinned", true, false);
|
||||
aTab.dispatchEvent(event);
|
||||
|
@ -70,6 +70,7 @@ function GroupItem(listOfEls, options) {
|
||||
options = {};
|
||||
|
||||
this._inited = false;
|
||||
this._uninited = false;
|
||||
this._children = []; // an array of Items
|
||||
this.defaultSize = new Point(TabItems.tabWidth * 1.5, TabItems.tabHeight * 1.5);
|
||||
this.isAGroupItem = true;
|
||||
@ -366,7 +367,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
// Function: save
|
||||
// Saves this groupItem to persistent storage.
|
||||
save: function GroupItem_save() {
|
||||
if (!this._inited) // too soon to save now
|
||||
if (!this._inited || this._uninited) // too soon/late to save
|
||||
return;
|
||||
|
||||
var data = this.getStorageData();
|
||||
@ -374,6 +375,14 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
Storage.saveGroupItem(gWindow, data);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: deleteData
|
||||
// Deletes the groupItem in the persistent storage.
|
||||
deleteData: function GroupItem_deleteData() {
|
||||
this._uninited = true;
|
||||
Storage.deleteGroupItem(gWindow, this.id);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: getTitle
|
||||
// Returns the title of this groupItem as a string.
|
||||
@ -561,7 +570,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
}
|
||||
});
|
||||
|
||||
Storage.deleteGroupItem(gWindow, this.id);
|
||||
this.deleteData();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -647,7 +656,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||
self.$undoContainer = null;
|
||||
Items.unsquish();
|
||||
|
||||
Storage.deleteGroupItem(gWindow, self.id);
|
||||
self.deleteData();
|
||||
};
|
||||
|
||||
this.$undoContainer.click(function(e) {
|
||||
@ -2072,7 +2081,7 @@ let GroupItems = {
|
||||
child.close();
|
||||
});
|
||||
|
||||
Storage.deleteGroupItem(gWindow, groupItem.id);
|
||||
groupItem.deleteData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -202,11 +202,10 @@ function TabItem(tab, options) {
|
||||
this._updateDebugBounds();
|
||||
|
||||
TabItems.register(this);
|
||||
|
||||
if (!this.reconnected) {
|
||||
|
||||
if (!this.reconnected)
|
||||
GroupItems.newTab(this, options);
|
||||
}
|
||||
|
||||
|
||||
// tabs which were not reconnected at all or were not immediately added
|
||||
// to a group get the same treatment.
|
||||
if (!this.reconnected || (reconnected && !reconnected.addedToGroup) ) {
|
||||
@ -804,7 +803,7 @@ let TabItems = {
|
||||
let oldURL = tabItem.url;
|
||||
tabItem.url = tabUrl;
|
||||
|
||||
if (!tabItem.reconnected && (oldURL == 'about:blank' || !oldURL))
|
||||
if (!tabItem.reconnected)
|
||||
this.reconnect(tabItem);
|
||||
|
||||
tabItem.save();
|
||||
@ -1057,10 +1056,10 @@ let TabItems = {
|
||||
item.reconnected = true;
|
||||
found = {addedToGroup: tabData.groupID};
|
||||
} else {
|
||||
// if it's not a blank tab or it belongs to a group, it would mean
|
||||
// the item is reconnected.
|
||||
item.reconnected =
|
||||
(item.tab.linkedBrowser.currentURI.spec != 'about:blank' || item.parent);
|
||||
// We should never have any orphaned tabs. Therefore, item is not
|
||||
// connected if it has no parent and GroupItems.newTab() would handle
|
||||
// the group creation.
|
||||
item.reconnected = (item.parent != null);
|
||||
}
|
||||
item.save();
|
||||
|
||||
|
@ -145,6 +145,7 @@ _BROWSER_FILES = \
|
||||
browser_bug561636.js \
|
||||
browser_bug562649.js \
|
||||
browser_bug563588.js \
|
||||
browser_bug575561.js \
|
||||
browser_bug577121.js \
|
||||
browser_bug579872.js \
|
||||
browser_bug580956.js \
|
||||
@ -218,6 +219,8 @@ _BROWSER_FILES = \
|
||||
file_bug550565_favicon.ico \
|
||||
browser_overLinkInLocationBar.js \
|
||||
browser_aboutHome.js \
|
||||
app_bug575561.html \
|
||||
app_subframe_bug575561.html \
|
||||
$(NULL)
|
||||
|
||||
# compartment-disabled
|
||||
|
16
browser/base/content/test/app_bug575561.html
Normal file
16
browser/base/content/test/app_bug575561.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=575561
|
||||
-->
|
||||
<head>
|
||||
<title>Test for links in app tabs</title>
|
||||
</head>
|
||||
<body>
|
||||
<a href="http://example.com/browser/browser/base/content/test/dummy_page.html">same domain</a>
|
||||
<a href="http://test1.example.com/browser/browser/base/content/test/dummy_page.html">same domain (different subdomain)</a>
|
||||
<a href="http://example.org/browser/browser/base/content/test/dummy_page.html">different domain</a>
|
||||
<a href="http://example.org/browser/browser/base/content/test/dummy_page.html" target="foo">different domain (with target)</a>
|
||||
<iframe src="app_subframe_bug575561.html"></iframe>
|
||||
</body>
|
||||
</html>
|
12
browser/base/content/test/app_subframe_bug575561.html
Normal file
12
browser/base/content/test/app_subframe_bug575561.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=575561
|
||||
-->
|
||||
<head>
|
||||
<title>Test for links in app tab subframes</title>
|
||||
</head>
|
||||
<body>
|
||||
<a href="http://example.org/browser/browser/base/content/test/dummy_page.html">different domain</a>
|
||||
</body>
|
||||
</html>
|
@ -608,6 +608,15 @@ function test() {
|
||||
Services.obs.addObserver(XPInstallObserver, "addon-install-complete", false);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
// Make sure no more test parts run in case we were timed out
|
||||
TESTS = [];
|
||||
|
||||
AddonManager.getAllInstalls(function(aInstalls) {
|
||||
aInstalls.forEach(function(aInstall) {
|
||||
aInstall.cancel();
|
||||
});
|
||||
});
|
||||
|
||||
Services.prefs.clearUserPref("extensions.logging.enabled");
|
||||
|
||||
Services.obs.removeObserver(XPInstallObserver, "addon-install-started");
|
||||
|
@ -17,8 +17,8 @@ function checkPopupHide()
|
||||
function checkPopupMessage(doc)
|
||||
{
|
||||
is(gInvalidFormPopup.firstChild.textContent,
|
||||
doc.getElementById('i').validationMessage.substring(0,256),
|
||||
"The panel should show the 256 first characters of the validationMessage");
|
||||
doc.getElementById('i').validationMessage,
|
||||
"The panel should show the message from validationMessage");
|
||||
}
|
||||
|
||||
let gObserver = {
|
||||
@ -132,50 +132,11 @@ function test3()
|
||||
gBrowser.selectedTab.linkedBrowser.loadURI(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* In this test, we check that the validation message is correctly cut.
|
||||
*/
|
||||
function test4()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i'><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
|
||||
gInvalidFormPopup.addEventListener("popupshown", function() {
|
||||
gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false);
|
||||
|
||||
let doc = gBrowser.contentDocument;
|
||||
is(doc.activeElement, doc.getElementById('i'),
|
||||
"First invalid element should be focused");
|
||||
|
||||
checkPopupShow();
|
||||
checkPopupMessage(doc);
|
||||
|
||||
// Clean-up and next test.
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
|
||||
executeSoon(test5);
|
||||
}, false);
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
let msg = "";
|
||||
for (let i=0; i<50; ++i) {
|
||||
msg += "abcde ";
|
||||
}
|
||||
// msg has 300 characters
|
||||
gBrowser.contentDocument.getElementById('i').setCustomValidity(msg);
|
||||
gBrowser.contentDocument.getElementById('s').click();
|
||||
}, true);
|
||||
|
||||
gBrowser.selectedTab = tab;
|
||||
gBrowser.selectedTab.linkedBrowser.loadURI(uri);
|
||||
}
|
||||
|
||||
/**
|
||||
* In this test, we check that, we can hide the popup by interacting with the
|
||||
* invalid element.
|
||||
*/
|
||||
function test5()
|
||||
function test4()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
@ -197,7 +158,7 @@ function test5()
|
||||
|
||||
// Clean-up and next test.
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
|
||||
executeSoon(test6);
|
||||
executeSoon(test5);
|
||||
});
|
||||
}, false);
|
||||
|
||||
@ -215,7 +176,7 @@ function test5()
|
||||
* In this test, we check that we can hide the popup by blurring the invalid
|
||||
* element.
|
||||
*/
|
||||
function test6()
|
||||
function test5()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
@ -237,7 +198,7 @@ function test6()
|
||||
|
||||
// Clean-up and next test.
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
|
||||
executeSoon(test7);
|
||||
executeSoon(test6);
|
||||
});
|
||||
}, false);
|
||||
|
||||
@ -254,7 +215,7 @@ function test6()
|
||||
/**
|
||||
* In this test, we check that we can hide the popup by pressing TAB.
|
||||
*/
|
||||
function test7()
|
||||
function test6()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
@ -276,7 +237,7 @@ function test7()
|
||||
|
||||
// Clean-up and next test.
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
|
||||
executeSoon(test8);
|
||||
executeSoon(test7);
|
||||
});
|
||||
}, false);
|
||||
|
||||
@ -293,7 +254,7 @@ function test7()
|
||||
/**
|
||||
* In this test, we check that the popup will hide if we move to another tab.
|
||||
*/
|
||||
function test8()
|
||||
function test7()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
@ -317,7 +278,7 @@ function test8()
|
||||
// Clean-up and next test.
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
|
||||
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
|
||||
executeSoon(test9);
|
||||
executeSoon(test8);
|
||||
});
|
||||
}, false);
|
||||
|
||||
@ -336,7 +297,7 @@ function test8()
|
||||
* invalid form is submitted in another tab than the current focused one
|
||||
* (submitted in background).
|
||||
*/
|
||||
function test9()
|
||||
function test8()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input id='i' required><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
@ -355,7 +316,7 @@ function test9()
|
||||
gBrowser.removeTab(tab, {animate: false});
|
||||
|
||||
// Next test
|
||||
executeSoon(test10);
|
||||
executeSoon(test9);
|
||||
});
|
||||
};
|
||||
|
||||
@ -376,7 +337,7 @@ function test9()
|
||||
/**
|
||||
* In this test, we check that the author defined error message is shown.
|
||||
*/
|
||||
function test10()
|
||||
function test9()
|
||||
{
|
||||
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input x-moz-errormessage='foo' required id='i'><input id='s' type='submit'></form>";
|
||||
let tab = gBrowser.addTab();
|
||||
|
77
browser/base/content/test/browser_bug575561.js
Normal file
77
browser/base/content/test/browser_bug575561.js
Normal file
@ -0,0 +1,77 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Pinned: Link to the same domain should not open a new tab
|
||||
// Tests link to http://example.com/browser/browser/base/content/test/dummy_page.html
|
||||
testLink(0, true, false, function() {
|
||||
// Pinned: Link to the same domain should not open a new tab
|
||||
// Tests link to http://test1.example.com/browser/browser/base/content/test/dummy_page.html
|
||||
testLink(1, true, false, function() {
|
||||
// Pinned: Link to a different domain should open a new tab
|
||||
// Tests link to http://example.org/browser/browser/base/content/test/dummy_page.html
|
||||
testLink(2, true, true, function() {
|
||||
// Not Pinned: Link to a different domain should not open a new tab
|
||||
// Tests link to http://example.org/browser/browser/base/content/test/dummy_page.html
|
||||
testLink(2, false, false, function() {
|
||||
// Pinned: Targetted link should open a new tab
|
||||
// Tests link to http://example.org/browser/browser/base/content/test/dummy_page.html with target="foo"
|
||||
testLink(3, true, true, function() {
|
||||
// Pinned: Link in a subframe should not open a new tab
|
||||
// Tests link to http://example.org/browser/browser/base/content/test/dummy_page.html in subframe
|
||||
testLink(0, true, false, finish, true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testLink(aLinkIndex, pinTab, expectNewTab, nextTest, testSubFrame) {
|
||||
let appTab = gBrowser.addTab("http://example.com/browser/browser/base/content/test/app_bug575561.html", {skipAnimation: true});
|
||||
if (pinTab)
|
||||
gBrowser.pinTab(appTab);
|
||||
gBrowser.selectedTab = appTab;
|
||||
appTab.linkedBrowser.addEventListener("load", onLoad, true);
|
||||
|
||||
let loadCount = 0;
|
||||
function onLoad() {
|
||||
loadCount++;
|
||||
if (loadCount < 2)
|
||||
return;
|
||||
|
||||
appTab.linkedBrowser.removeEventListener("load", onLoad, true);
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(appTab);
|
||||
if (testSubFrame)
|
||||
browser = browser.contentDocument.getElementsByTagName("iframe")[0];
|
||||
|
||||
let links = browser.contentDocument.getElementsByTagName("a");
|
||||
|
||||
if (expectNewTab)
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true);
|
||||
else
|
||||
browser.addEventListener("load", onPageLoad, true);
|
||||
|
||||
info("Clicking " + links[aLinkIndex].textContent);
|
||||
EventUtils.sendMouseEvent({type:"click"}, links[aLinkIndex], browser.contentWindow);
|
||||
|
||||
function onPageLoad() {
|
||||
browser.removeEventListener("load", onPageLoad, true);
|
||||
is(browser.contentDocument.location.href, links[aLinkIndex].href, "Link should not open in a new tab");
|
||||
executeSoon(function(){
|
||||
gBrowser.removeTab(appTab);
|
||||
nextTest();
|
||||
});
|
||||
}
|
||||
|
||||
function onTabOpen(event) {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true);
|
||||
ok(true, "Link should open a new tab");
|
||||
executeSoon(function(){
|
||||
gBrowser.removeTab(appTab);
|
||||
gBrowser.removeCurrentTab();
|
||||
nextTest();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
var tab;
|
||||
var performedTest = false;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
@ -7,25 +6,31 @@ function test() {
|
||||
tab = gBrowser.addTab();
|
||||
isnot(tab.getAttribute("fadein"), "true", "newly opened tab is yet to fade in");
|
||||
|
||||
// Remove the tab right before the opening animation's first frame
|
||||
// Try to remove the tab right before the opening animation's first frame
|
||||
window.mozRequestAnimationFrame(checkAnimationState);
|
||||
executeSoon(checkAnimationState);
|
||||
}
|
||||
|
||||
function checkAnimationState() {
|
||||
if (performedTest)
|
||||
return;
|
||||
|
||||
if (tab.getAttribute("fadein") != "true") {
|
||||
window.mozRequestAnimationFrame(checkAnimationState);
|
||||
executeSoon(checkAnimationState);
|
||||
return;
|
||||
}
|
||||
|
||||
performedTest = true;
|
||||
|
||||
info(window.getComputedStyle(tab).maxWidth);
|
||||
gBrowser.removeTab(tab, {animate:true});
|
||||
ok(!tab.parentNode, "tab successfully removed");
|
||||
finish();
|
||||
gBrowser.removeTab(tab, { animate: true });
|
||||
if (!tab.parentNode) {
|
||||
ok(true, "tab removed synchronously since the opening animation hasn't moved yet");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
info("tab didn't close immediately, so the tab opening animation must have started moving");
|
||||
info("waiting for the tab to close asynchronously");
|
||||
tab.addEventListener("transitionend", function (event) {
|
||||
if (event.propertyName == "max-width")
|
||||
executeSoon(function () {
|
||||
ok(!tab.parentNode, "tab removed asynchronously");
|
||||
finish();
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug595804.js \
|
||||
browser_tabview_bug595930.js \
|
||||
browser_tabview_bug595943.js \
|
||||
browser_tabview_bug598600.js \
|
||||
browser_tabview_dragdrop.js \
|
||||
browser_tabview_exit_button.js \
|
||||
browser_tabview_group.js \
|
||||
@ -67,6 +68,7 @@ _BROWSER_FILES = \
|
||||
browser_tabview_startup_transitions.js \
|
||||
browser_tabview_undo_group.js \
|
||||
browser_tabview_firstrun_pref.js \
|
||||
head.js \
|
||||
search1.html \
|
||||
search2.html \
|
||||
$(NULL)
|
||||
|
@ -59,7 +59,7 @@ function test() {
|
||||
"The currently selected tab should be the first tab in the groupItemOne");
|
||||
|
||||
// create another group with a tab.
|
||||
let groupItemTwo = createEmptyGroupItem(contentWindow, 200);
|
||||
let groupItemTwo = createEmptyGroupItem(contentWindow, 300, 300, 200);
|
||||
|
||||
let onTabViewHidden = function() {
|
||||
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
@ -111,16 +111,3 @@ function testGroupSwitch(contentWindow, groupItemOne, groupItemTwo) {
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
function createEmptyGroupItem(contentWindow, padding) {
|
||||
let pageBounds = contentWindow.Items.getPageBounds();
|
||||
pageBounds.inset(padding, padding);
|
||||
|
||||
let box = new contentWindow.Rect(pageBounds);
|
||||
box.width = 300;
|
||||
box.height = 300;
|
||||
|
||||
let emptyGroupItem = new contentWindow.GroupItem([], { bounds: box });
|
||||
|
||||
return emptyGroupItem;
|
||||
}
|
||||
|
115
browser/base/content/test/tabview/browser_tabview_bug598600.js
Normal file
115
browser/base/content/test/tabview/browser_tabview_bug598600.js
Normal file
@ -0,0 +1,115 @@
|
||||
/* ***** 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 tabview bug598600 test.
|
||||
*
|
||||
* 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):
|
||||
* Raymond Lee <raymond@appcoast.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 ***** */
|
||||
let newWin;
|
||||
let prefService;
|
||||
|
||||
function test() {
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
prefService =
|
||||
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
|
||||
getBranch("browser.panorama.");
|
||||
// make sure we don't trigger the 'first run' behavior
|
||||
prefService.setBoolPref("experienced_first_run", true);
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
// open a new window and setup the window state.
|
||||
newWin = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
|
||||
newWin.addEventListener("load", function(event) {
|
||||
this.removeEventListener("load", arguments.callee, false);
|
||||
|
||||
let newState = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ "url": "about:blank" }],
|
||||
hidden: true,
|
||||
attributes: {},
|
||||
extData: {
|
||||
"tabview-tab":
|
||||
'{"bounds":{"left":20,"top":35,"width":280,"height":210},' +
|
||||
'"userSize":null,"url":"about:blank","groupID":1,' +
|
||||
'"imageData":null,"title":null}'
|
||||
}
|
||||
},{
|
||||
entries: [{ url: "about:blank" }],
|
||||
index: 1,
|
||||
hidden: false,
|
||||
attributes: {},
|
||||
extData: {
|
||||
"tabview-tab":
|
||||
'{"bounds":{"left":375,"top":35,"width":280,"height":210},' +
|
||||
'"userSize":null,"url":"about:blank","groupID":2,' +
|
||||
'"imageData":null,"title":null}'
|
||||
}
|
||||
}],
|
||||
selected:2,
|
||||
_closedTabs: [],
|
||||
extData: {
|
||||
"tabview-groups": '{"nextID":3,"activeGroupId":2}',
|
||||
"tabview-group":
|
||||
'{"1":{"bounds":{"left":15,"top":10,"width":320,"height":375},' +
|
||||
'"userSize":null,"locked":{},"title":"","id":1},' +
|
||||
'"2":{"bounds":{"left":380,"top":5,"width":320,"height":375},' +
|
||||
'"userSize":null,"locked":{},"title":"","id":2}}',
|
||||
"tabview-ui": '{"pageBounds":{"left":0,"top":0,"width":875,"height":650}}'
|
||||
}, sizemode:"normal"
|
||||
}]
|
||||
};
|
||||
ss.setWindowState(newWin, JSON.stringify(newState), true);
|
||||
|
||||
// add a new tab.
|
||||
newWin.gBrowser.addTab();
|
||||
is(newWin.gBrowser.tabs.length, 3, "There are 3 browser tabs");
|
||||
|
||||
let onTabViewShow = function() {
|
||||
newWin.removeEventListener("tabviewshown", onTabViewShow, false);
|
||||
|
||||
let contentWindow = newWin.document.getElementById("tab-view").contentWindow;
|
||||
|
||||
is(contentWindow.GroupItems.groupItems.length, 2, "Has two group items");
|
||||
is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphan tabs");
|
||||
|
||||
// clean up and finish
|
||||
prefService.setBoolPref("experienced_first_run", false);
|
||||
newWin.close();
|
||||
|
||||
finish();
|
||||
}
|
||||
newWin.addEventListener("tabviewshown", onTabViewShow, false);
|
||||
newWin.TabView.toggle();
|
||||
}, false);
|
||||
}
|
@ -95,10 +95,8 @@ function addTest(contentWindow, groupOneId, groupTwoId, originalTab) {
|
||||
ok(tabItem, "The tab item exists");
|
||||
|
||||
// calculate the offsets
|
||||
let groupTwoRect = groupTwo.getBounds();
|
||||
let groupTwoRectCenter = groupTwoRect.center();
|
||||
let tabItemRect = tabItem.getBounds();
|
||||
let tabItemRectCenter = tabItemRect.center();
|
||||
let groupTwoRectCenter = groupTwo.getBounds().center();
|
||||
let tabItemRectCenter = tabItem.getBounds().center();
|
||||
let offsetX =
|
||||
Math.round(groupTwoRectCenter.x - tabItemRectCenter.x);
|
||||
let offsetY =
|
||||
@ -132,41 +130,23 @@ function addTest(contentWindow, groupOneId, groupTwoId, originalTab) {
|
||||
simulateDragDrop(tabItem.container, offsetX, offsetY, contentWindow);
|
||||
}
|
||||
|
||||
function simulateDragDrop(tabItem, offsetX, offsetY, contentWindow) {
|
||||
// enter drag mode
|
||||
let dataTransfer;
|
||||
function simulateDragDrop(element, offsetX, offsetY, contentWindow) {
|
||||
let rect = element.getBoundingClientRect();
|
||||
let startX = (rect.right - rect.left)/2;
|
||||
let startY = (rect.bottom - rect.top)/2;
|
||||
let incrementX = offsetX / 2;
|
||||
let incrementY = offsetY / 2;
|
||||
|
||||
EventUtils.synthesizeMouse(
|
||||
tabItem, 1, 1, { type: "mousedown" }, contentWindow);
|
||||
event = contentWindow.document.createEvent("DragEvents");
|
||||
event.initDragEvent(
|
||||
"dragenter", true, true, contentWindow, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 1, null, dataTransfer);
|
||||
tabItem.dispatchEvent(event);
|
||||
|
||||
// drag over
|
||||
if (offsetX || offsetY) {
|
||||
let Ci = Components.interfaces;
|
||||
let utils = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDOMWindowUtils);
|
||||
let rect = tabItem.getBoundingClientRect();
|
||||
for (let i = 1; i <= 5; i++) {
|
||||
let left = rect.left + Math.round(i * offsetX / 5);
|
||||
let top = rect.top + Math.round(i * offsetY / 5);
|
||||
utils.sendMouseEvent("mousemove", left, top, 0, 1, 0);
|
||||
}
|
||||
event = contentWindow.document.createEvent("DragEvents");
|
||||
event.initDragEvent(
|
||||
"dragover", true, true, contentWindow, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
tabItem.dispatchEvent(event);
|
||||
}
|
||||
element, startX, startY, { type: "mousedown" });
|
||||
|
||||
// drop
|
||||
EventUtils.synthesizeMouse(tabItem, 0, 0, { type: "mouseup" }, contentWindow);
|
||||
event = contentWindow.document.createEvent("DragEvents");
|
||||
event.initDragEvent(
|
||||
"drop", true, true, contentWindow, 0, 0, 0, 0, 0,
|
||||
false, false, false, false, 0, null, dataTransfer);
|
||||
tabItem.dispatchEvent(event);
|
||||
for (let i = 1; i <= 2; i++) {
|
||||
EventUtils.synthesizeMouse(
|
||||
element, (startX + incrementX * i), (startY + incrementY * i),
|
||||
{ type: "mousemove" });
|
||||
}
|
||||
|
||||
EventUtils.synthesizeMouse(
|
||||
element, (startX + incrementX * 2), (startY + incrementY * 2),
|
||||
{ type: "mouseup" });
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ function testEmptyGroupItem(contentWindow) {
|
||||
let groupItemCount = contentWindow.GroupItems.groupItems.length;
|
||||
|
||||
// create empty group item
|
||||
let emptyGroupItem = createEmptyGroupItem(contentWindow, 100);
|
||||
let emptyGroupItem = createEmptyGroupItem(contentWindow, 300, 300, 100, true);
|
||||
ok(emptyGroupItem.isEmpty(), "This group is empty");
|
||||
|
||||
is(contentWindow.GroupItems.groupItems.length, ++groupItemCount,
|
||||
@ -89,7 +89,7 @@ function testEmptyGroupItem(contentWindow) {
|
||||
}
|
||||
|
||||
function testGroupItemWithTabItem(contentWindow) {
|
||||
let groupItem = createEmptyGroupItem(contentWindow, 200);
|
||||
let groupItem = createEmptyGroupItem(contentWindow, 300, 300, 200, true);
|
||||
let tabItemCount = 0;
|
||||
|
||||
let onTabViewHidden = function() {
|
||||
@ -161,17 +161,3 @@ function testGroupItemWithTabItem(contentWindow) {
|
||||
|
||||
EventUtils.synthesizeMouse(newTabButton[0], 1, 1, {}, contentWindow);
|
||||
}
|
||||
|
||||
function createEmptyGroupItem(contentWindow, padding) {
|
||||
let pageBounds = contentWindow.Items.getPageBounds();
|
||||
pageBounds.inset(padding, padding);
|
||||
|
||||
let box = new contentWindow.Rect(pageBounds);
|
||||
box.width = 300;
|
||||
box.height = 300;
|
||||
|
||||
let emptyGroupItem = new contentWindow.GroupItem([], { bounds: box,
|
||||
immediately: true });
|
||||
|
||||
return emptyGroupItem;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ function onTabViewWindowLoaded() {
|
||||
is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphaned tabs");
|
||||
|
||||
// 2) create a group, add a blank tab
|
||||
let groupItem = createEmptyGroupItem(contentWindow, 200);
|
||||
let groupItem = createEmptyGroupItem(contentWindow, 300, 300, 200);
|
||||
|
||||
let onTabViewHidden = function() {
|
||||
newWin.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
@ -110,19 +110,6 @@ function onTabViewWindowLoaded() {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, newTabButton[0], contentWindow);
|
||||
}
|
||||
|
||||
function createEmptyGroupItem(contentWindow, padding) {
|
||||
let pageBounds = contentWindow.Items.getPageBounds();
|
||||
pageBounds.inset(padding, padding);
|
||||
|
||||
let box = new contentWindow.Rect(pageBounds);
|
||||
box.width = 300;
|
||||
box.height = 300;
|
||||
|
||||
let emptyGroupItem = new contentWindow.GroupItem([], { bounds: box });
|
||||
|
||||
return emptyGroupItem;
|
||||
}
|
||||
|
||||
function whenWindowObservesOnce(win, topic, callback) {
|
||||
let windowWatcher =
|
||||
Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher);
|
||||
|
@ -1,4 +1,3 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@ -12,14 +11,15 @@
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Fenntrolysis.
|
||||
* The Original Code is the utilities for tabview.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Nokia.
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Raymond Lee <raymond@appcoast.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
|
||||
@ -35,20 +35,17 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
include protocol PBrowser;
|
||||
function createEmptyGroupItem(contentWindow, width, height, padding, noAnimation) {
|
||||
let pageBounds = contentWindow.Items.getPageBounds();
|
||||
pageBounds.inset(padding, padding);
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
let box = new contentWindow.Rect(pageBounds);
|
||||
box.width = width;
|
||||
box.height = height;
|
||||
|
||||
let immediately = noAnimation ? true: false;
|
||||
let emptyGroupItem =
|
||||
new contentWindow.GroupItem([], { bounds: box, immediately: immediately });
|
||||
|
||||
protocol PDocumentRendererNativeID
|
||||
{
|
||||
manager PBrowser;
|
||||
|
||||
parent:
|
||||
// Returns the offset, width and height, in pixels, of the area in the
|
||||
// buffer that was drawn.
|
||||
__delete__(PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h, PRUint32 nativeID);
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
return emptyGroupItem;
|
||||
}
|
@ -130,11 +130,24 @@
|
||||
if (!pasteAndGo)
|
||||
return;
|
||||
var controller = document.commandDispatcher.getControllerForCommand("cmd_paste");
|
||||
var enabled = controller.isCommandEnabled("cmd_paste");
|
||||
if (enabled)
|
||||
pasteAndGo.removeAttribute("disabled");
|
||||
else
|
||||
pasteAndGo.setAttribute("disabled", "true");
|
||||
var couldBeURL = controller.isCommandEnabled("cmd_paste");
|
||||
if (couldBeURL) {
|
||||
let cbSvc = Cc["@mozilla.org/widget/clipboard;1"].
|
||||
getService(Ci.nsIClipboard);
|
||||
let xferable = Cc["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Ci.nsITransferable);
|
||||
xferable.addDataFlavor("text/unicode");
|
||||
cbSvc.getData(xferable, cbSvc.kGlobalClipboard);
|
||||
let data = {};
|
||||
xferable.getTransferData("text/unicode", data, {});
|
||||
data = data.value.QueryInterface(Ci.nsISupportsString).data;
|
||||
try {
|
||||
makeURI(data);
|
||||
} catch (ex) { // clipboard data is not a URL
|
||||
couldBeURL = false;
|
||||
}
|
||||
}
|
||||
pasteAndGo.hidden = !couldBeURL;
|
||||
}, false);
|
||||
|
||||
var insertLocation = cxmenu.firstChild;
|
||||
@ -147,7 +160,8 @@
|
||||
GetStringFromName("pasteAndGo.label");
|
||||
pasteAndGo.setAttribute("label", label);
|
||||
pasteAndGo.setAttribute("anonid", "paste-and-go");
|
||||
pasteAndGo.setAttribute("oncommand", "goDoCommand('cmd_paste'); gURLBar.handleCommand();");
|
||||
pasteAndGo.setAttribute("oncommand",
|
||||
"gURLBar.value = ''; goDoCommand('cmd_paste'); gURLBar.handleCommand();");
|
||||
cxmenu.insertBefore(pasteAndGo, insertLocation.nextSibling);
|
||||
}
|
||||
]]></constructor>
|
||||
|
@ -483,7 +483,7 @@ function openTroubleshootingPage()
|
||||
*/
|
||||
function openFeedbackPage()
|
||||
{
|
||||
openUILinkIn("http://input.mozilla.com/sad", "tab");
|
||||
openUILinkIn("http://input.mozilla.com/feedback", "tab");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1161,7 +1161,8 @@ var gEditItemOverlay = {
|
||||
this._folderMenuList.selectedItem = folderItem;
|
||||
},
|
||||
|
||||
onItemAdded: function EIO_onItemAdded(aItemId, aFolder, aIndex, aItemType) {
|
||||
onItemAdded: function EIO_onItemAdded(aItemId, aFolder, aIndex, aItemType,
|
||||
aURI) {
|
||||
this._lastNewItem = aItemId;
|
||||
},
|
||||
|
||||
|
@ -46,8 +46,6 @@
|
||||
<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE page [
|
||||
<!ENTITY % historyDTD SYSTEM "chrome://browser/locale/history/history.dtd">
|
||||
%historyDTD;
|
||||
<!ENTITY % placesDTD SYSTEM "chrome://browser/locale/places/places.dtd">
|
||||
%placesDTD;
|
||||
]>
|
||||
|
@ -391,7 +391,7 @@
|
||||
<vbox id="defaultView" flex="1">
|
||||
<vbox id="searchModifiers" hidden="true">
|
||||
<toolbar id="organizerScopeBar" class="chromeclass-toolbar" align="center">
|
||||
<label id="scopeBarTitle" value="&search.label;"/>
|
||||
<label id="scopeBarTitle" value="&search.in.label;"/>
|
||||
<toolbarbutton id="scopeBarAll" type="radio" group="scopeBar"
|
||||
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
|
||||
label="&search.scopeBookmarks.label;"
|
||||
|
@ -204,7 +204,7 @@ var bookmarksObserver = {
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex) {
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex, aURI) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
|
||||
|
@ -223,7 +223,7 @@ var bookmarksObserver = {
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex,
|
||||
aItemType) {
|
||||
aItemType, aURI) {
|
||||
var views = getViewsForFolder(aFolderId);
|
||||
ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
|
||||
|
||||
|
@ -53,7 +53,7 @@ var observer = {
|
||||
onEndUpdateBatch: function() {
|
||||
this._endUpdateBatch = true;
|
||||
},
|
||||
onItemAdded: function(id, folder, index, itemType) {
|
||||
onItemAdded: function(id, folder, index, itemType, uri) {
|
||||
this._itemAddedId = id;
|
||||
this._itemAddedParent = folder;
|
||||
this._itemAddedIndex = index;
|
||||
|
@ -35,7 +35,7 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This test makes sure that browsingmode attribute of the window is correctly
|
||||
// This test makes sure that privatebrowsingmode attribute of the window is correctly
|
||||
// switched with private browsing mode changes.
|
||||
|
||||
function test() {
|
||||
@ -45,20 +45,20 @@ function test() {
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
let docRoot = document.documentElement;
|
||||
|
||||
is(docRoot.getAttribute("browsingmode"), "normal",
|
||||
"browsingmode should be \"normal\" initially");
|
||||
ok(!docRoot.hasAttribute("privatebrowsingmode"),
|
||||
"privatebrowsingmode should not be present in normal mode");
|
||||
|
||||
// enter private browsing mode
|
||||
pb.privateBrowsingEnabled = true;
|
||||
|
||||
is(docRoot.getAttribute("browsingmode"), "private",
|
||||
"browsingmode should be \"private\" inside the private browsing mode");
|
||||
is(docRoot.getAttribute("privatebrowsingmode"), "temporary",
|
||||
"privatebrowsingmode should be \"temporary\" inside the private browsing mode");
|
||||
|
||||
// leave private browsing mode
|
||||
pb.privateBrowsingEnabled = false;
|
||||
|
||||
is(docRoot.getAttribute("browsingmode"), "normal",
|
||||
"browsingmode should be \"normal\" outside the private browsing mode");
|
||||
ok(!docRoot.hasAttribute("privatebrowsingmode"),
|
||||
"privatebrowsingmode should not be present in normal mode");
|
||||
|
||||
// cleanup
|
||||
gPrefService.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
|
@ -604,7 +604,8 @@
|
||||
label = this._stringBundle.getString("cmd_pasteAndSearch");
|
||||
element.setAttribute("label", label);
|
||||
element.setAttribute("anonid", "paste-and-search");
|
||||
element.setAttribute("oncommand", "goDoCommand('cmd_paste'); document.getElementById('searchbar').handleSearchCommand();");
|
||||
element.setAttribute("oncommand",
|
||||
"BrowserSearch.searchBar.value = ''; goDoCommand('cmd_paste'); BrowserSearch.searchBar.handleSearchCommand();");
|
||||
cxmenu.insertBefore(element, insertLocation.nextSibling);
|
||||
pasteAndSearch = element;
|
||||
}
|
||||
|
@ -45,8 +45,9 @@ include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_TEST_FILES = browser_405664.js \
|
||||
browser_415700.js \
|
||||
browser_addEngine.js \
|
||||
testEngine.xml \
|
||||
testEngine.src \
|
||||
browser_426329.js \
|
||||
426329.xml \
|
||||
browser_483086.js \
|
||||
|
@ -1,85 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ryan Flint <rflint@dslr.net> (Original Author)
|
||||
*
|
||||
* 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 ***** */
|
||||
var gSS = Services.search;
|
||||
|
||||
function observers(aSubject, aTopic, aData) {
|
||||
switch (aData) {
|
||||
case "engine-added":
|
||||
test2();
|
||||
break;
|
||||
case "engine-current":
|
||||
test3();
|
||||
break;
|
||||
case "engine-removed":
|
||||
test4();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
Services.obs.addObserver(observers, "browser-search-engine-modified", false);
|
||||
|
||||
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
|
||||
Ci.nsISearchEngine.DATA_XML, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
|
||||
false);
|
||||
}
|
||||
|
||||
function test2() {
|
||||
var engine = gSS.getEngineByName("Foo");
|
||||
ok(engine, "Engine was added.");
|
||||
|
||||
var aEngine = gSS.getEngineByAlias("fooalias");
|
||||
ok(!aEngine, "Alias was not parsed from engine description");
|
||||
|
||||
gSS.currentEngine = engine;
|
||||
}
|
||||
|
||||
function test3() {
|
||||
var engine = gSS.currentEngine;
|
||||
is(engine.name, "Foo", "Current engine was changed successfully");
|
||||
|
||||
gSS.removeEngine(engine);
|
||||
}
|
||||
|
||||
function test4() {
|
||||
var engine = gSS.currentEngine;
|
||||
ok(engine, "An engine is present.");
|
||||
isnot(engine.name, "Foo", "Current engine reset after removal");
|
||||
|
||||
Services.obs.removeObserver(observers, "browser-search-engine-modified");
|
||||
finish();
|
||||
}
|
168
browser/components/search/test/browser_addEngine.js
Normal file
168
browser/components/search/test/browser_addEngine.js
Normal file
@ -0,0 +1,168 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ryan Flint <rflint@dslr.net> (Original Author)
|
||||
*
|
||||
* 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 ***** */
|
||||
var gSS = Services.search;
|
||||
|
||||
function observer(aSubject, aTopic, aData) {
|
||||
if (!gCurrentTest) {
|
||||
info("Observer called with no test active");
|
||||
return;
|
||||
}
|
||||
|
||||
let engine = aSubject.QueryInterface(Ci.nsISearchEngine);
|
||||
info("Observer: " + aData + " for " + engine.name);
|
||||
let method;
|
||||
switch (aData) {
|
||||
case "engine-added":
|
||||
if (gCurrentTest.added)
|
||||
method = "added"
|
||||
break;
|
||||
case "engine-current":
|
||||
if (gCurrentTest.current)
|
||||
method = "current";
|
||||
break;
|
||||
case "engine-removed":
|
||||
if (gCurrentTest.removed)
|
||||
method = "removed";
|
||||
break;
|
||||
}
|
||||
|
||||
if (method)
|
||||
gCurrentTest[method](engine);
|
||||
}
|
||||
|
||||
function checkEngine(checkObj, engineObj) {
|
||||
info("Checking engine");
|
||||
for (var prop in checkObj)
|
||||
is(checkObj[prop], engineObj[prop], prop + " is correct");
|
||||
}
|
||||
|
||||
var gTests = [
|
||||
{
|
||||
name: "opensearch install",
|
||||
engine: {
|
||||
name: "Foo",
|
||||
alias: null,
|
||||
description: "Foo Search",
|
||||
searchForm: "http://mochi.test:8888/browser/browser/components/search/test/",
|
||||
type: Ci.nsISearchEngine.TYPE_OPENSEARCH
|
||||
},
|
||||
run: function () {
|
||||
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.xml",
|
||||
Ci.nsISearchEngine.DATA_XML, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
|
||||
false);
|
||||
},
|
||||
added: function (engine) {
|
||||
ok(engine, "engine was added.");
|
||||
|
||||
checkEngine(this.engine, engine);
|
||||
|
||||
let engineFromSS = gSS.getEngineByName(this.engine.name);
|
||||
is(engine, engineFromSS, "engine is obtainable via getEngineByName");
|
||||
|
||||
let aEngine = gSS.getEngineByAlias("fooalias");
|
||||
ok(!aEngine, "Alias was not parsed from engine description");
|
||||
|
||||
gSS.currentEngine = engine;
|
||||
},
|
||||
current: function (engine) {
|
||||
let currentEngine = gSS.currentEngine;
|
||||
is(engine, currentEngine, "engine is current");
|
||||
is(engine.name, this.engine.name, "current engine was changed successfully");
|
||||
|
||||
gSS.removeEngine(engine);
|
||||
},
|
||||
removed: function (engine) {
|
||||
let currentEngine = gSS.currentEngine;
|
||||
ok(currentEngine, "An engine is present.");
|
||||
isnot(currentEngine.name, this.engine.name, "Current engine reset after removal");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "sherlock install",
|
||||
engine: {
|
||||
name: "Test Sherlock",
|
||||
alias: null,
|
||||
description: "Test Description",
|
||||
searchForm: "http://example.com/searchform",
|
||||
type: Ci.nsISearchEngine.TYPE_SHERLOCK
|
||||
},
|
||||
run: function () {
|
||||
gSS.addEngine("http://mochi.test:8888/browser/browser/components/search/test/testEngine.src",
|
||||
Ci.nsISearchEngine.DATA_TEXT, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAABGklEQVQoz2NgGB6AnZ1dUlJSXl4eSDIyMhLW4Ovr%2B%2Fr168uXL69Zs4YoG%2BLi4i5dusTExMTGxsbNzd3f37937976%2BnpmZmagbHR09J49e5YvX66kpATVEBYW9ubNm2nTphkbG7e2tp44cQLIuHfvXm5urpaWFlDKysqqu7v73LlzECMYIiIiHj58mJCQoKKicvXq1bS0NKBgW1vbjh074uPjgeqAXE1NzSdPnvDz84M0AEUvXLgAsW379u1z5swBen3jxo2zZ892cHB4%2BvQp0KlAfwI1cHJyghQFBwfv2rULokFXV%2FfixYu7d%2B8GGqGgoMDKyrpu3br9%2B%2FcDuXl5eVA%2FAEWBfoWHAdAYoNuAYQ0XAeoUERFhGDYAAPoUaT2dfWJuAAAAAElFTkSuQmCC",
|
||||
false);
|
||||
},
|
||||
added: function (engine) {
|
||||
ok(engine, "engine was added.");
|
||||
checkEngine(this.engine, engine);
|
||||
|
||||
let engineFromSS = gSS.getEngineByName(this.engine.name);
|
||||
is(engineFromSS, engine, "engine is obtainable via getEngineByName");
|
||||
|
||||
gSS.removeEngine(engine);
|
||||
},
|
||||
removed: function (engine) {
|
||||
let currentEngine = gSS.currentEngine;
|
||||
ok(currentEngine, "An engine is present.");
|
||||
isnot(currentEngine.name, this.engine.name, "Current engine reset after removal");
|
||||
|
||||
nextTest();
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
var gCurrentTest = null;
|
||||
function nextTest() {
|
||||
if (gTests.length) {
|
||||
gCurrentTest = gTests.shift();
|
||||
info("Running " + gCurrentTest.name);
|
||||
gCurrentTest.run();
|
||||
} else
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
Services.obs.addObserver(observer, "browser-search-engine-modified", false);
|
||||
registerCleanupFunction(cleanup);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
Services.obs.removeObserver(observer, "browser-search-engine-modified");
|
||||
}
|
11
browser/components/search/test/testEngine.src
Normal file
11
browser/components/search/test/testEngine.src
Normal file
@ -0,0 +1,11 @@
|
||||
<search
|
||||
name="Test Sherlock"
|
||||
description="Test Description"
|
||||
method="GET"
|
||||
searchform="http://example.com/searchform"
|
||||
action="http://example.com/action"
|
||||
queryCharset="UTF-8"
|
||||
>
|
||||
<input name="userParam" user>
|
||||
<input name="param" value="value">
|
||||
</search>
|
@ -36,6 +36,7 @@
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var gStateObject;
|
||||
var gTreeData;
|
||||
@ -54,13 +55,26 @@ window.onload = function() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
|
||||
if (sessionData.value.charAt(0) == '(')
|
||||
sessionData.value = sessionData.value.slice(1, -1);
|
||||
try {
|
||||
gStateObject = JSON.parse(sessionData.value);
|
||||
}
|
||||
catch (exJSON) {
|
||||
var s = new Cu.Sandbox("about:blank");
|
||||
gStateObject = Cu.evalInSandbox("(" + sessionData.value + ")", s);
|
||||
// If we couldn't parse the string with JSON.parse originally, make sure
|
||||
// that the value in the textbox will be parsable.
|
||||
sessionData.value = JSON.stringify(gStateObject);
|
||||
}
|
||||
|
||||
// make sure the data is tracked to be restored in case of a subsequent crash
|
||||
var event = document.createEvent("UIEvents");
|
||||
event.initUIEvent("input", true, true, window, 0);
|
||||
sessionData.dispatchEvent(event);
|
||||
|
||||
gStateObject = JSON.parse(sessionData.value);
|
||||
|
||||
|
||||
initTreeView();
|
||||
|
||||
document.getElementById("errorTryAgain").focus();
|
||||
|
@ -1268,15 +1268,32 @@ SessionStoreService.prototype = {
|
||||
},
|
||||
|
||||
getTabValue: function sss_getTabValue(aTab, aKey) {
|
||||
var data = aTab.__SS_extdata || {};
|
||||
let data = {};
|
||||
if (aTab.__SS_extdata) {
|
||||
data = aTab.__SS_extdata;
|
||||
}
|
||||
else if (aTab.linkedBrowser.__SS_data && aTab.linkedBrowser.__SS_data.extData) {
|
||||
// If the tab hasn't been fully restored, get the data from the to-be-restored data
|
||||
data = aTab.linkedBrowser.__SS_data.extData;
|
||||
}
|
||||
return data[aKey] || "";
|
||||
},
|
||||
|
||||
setTabValue: function sss_setTabValue(aTab, aKey, aStringValue) {
|
||||
if (!aTab.__SS_extdata) {
|
||||
aTab.__SS_extdata = {};
|
||||
// If the tab hasn't been restored, then set the data there, otherwise we
|
||||
// could lose newly added data.
|
||||
let saveTo;
|
||||
if (aTab.__SS_extdata) {
|
||||
saveTo = aTab.__SS_extdata;
|
||||
}
|
||||
aTab.__SS_extdata[aKey] = aStringValue;
|
||||
else if (aTab.linkedBrowser.__SS_data && aTab.linkedBrowser.__SS_data.extData) {
|
||||
saveTo = aTab.linkedBrowser.__SS_data.extData;
|
||||
}
|
||||
else {
|
||||
aTab.__SS_extdata = {};
|
||||
saveTo = aTab.__SS_extdata;
|
||||
}
|
||||
saveTo[aKey] = aStringValue;
|
||||
this.saveStateDelayed(aTab.ownerDocument.defaultView);
|
||||
},
|
||||
|
||||
|
@ -117,8 +117,10 @@ _BROWSER_TEST_FILES = \
|
||||
browser_579868.js \
|
||||
browser_579879.js \
|
||||
browser_580512.js \
|
||||
browser_581593.js \
|
||||
browser_586147.js \
|
||||
browser_586068-cascaded_restore.js \
|
||||
browser_590268.js \
|
||||
browser_600545.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
/* ***** 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 sessionstore test 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):
|
||||
* Paul O’Shannessy <paul@oshannessy.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 ***** */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
|
||||
let stateBackup = ss.getBrowserState();
|
||||
|
||||
|
||||
function test() {
|
||||
/** Test for bug 581593 **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
let oldState = { windows: [{ tabs: [{ entries: [{ url: "example.com" }] }] }]};
|
||||
let pageData = {
|
||||
url: "about:sessionrestore",
|
||||
formdata: { "#sessionData": "(" + JSON.stringify(oldState) + ")" }
|
||||
};
|
||||
let state = { windows: [{ tabs: [{ entries: [pageData] }] }] };
|
||||
|
||||
// The form data will be restored before SSTabRestored, so we want to listen
|
||||
// for that on the currently selected tab (it will be reused)
|
||||
gBrowser.selectedTab.addEventListener("SSTabRestored", onSSTabRestored, true);
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function onSSTabRestored(aEvent) {
|
||||
info("SSTabRestored event");
|
||||
gBrowser.selectedTab.removeEventListener("SSTabRestored", onSSTabRestored, true);
|
||||
gBrowser.selectedBrowser.addEventListener("input", onInput, true);
|
||||
}
|
||||
|
||||
function onInput(aEvent) {
|
||||
info("input event");
|
||||
gBrowser.selectedBrowser.removeEventListener("input", onInput, true);
|
||||
|
||||
// This is an ok way to check this because we will make sure that the text
|
||||
// field is parsable.
|
||||
let val = gBrowser.selectedBrowser.contentDocument.getElementById("sessionData").value;
|
||||
try {
|
||||
JSON.parse(val);
|
||||
ok(true, "JSON.parse succeeded");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "JSON.parse failed");
|
||||
}
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
}
|
||||
|
148
browser/components/sessionstore/test/browser/browser_590268.js
Normal file
148
browser/components/sessionstore/test/browser/browser_590268.js
Normal file
@ -0,0 +1,148 @@
|
||||
/* ***** 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 sessionstore test 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):
|
||||
* Paul O’Shannessy <paul@oshannessy.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 ***** */
|
||||
|
||||
const NUM_TABS = 12;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
|
||||
let stateBackup = ss.getBrowserState();
|
||||
|
||||
|
||||
function test() {
|
||||
/** Test for Bug 590268 - Provide access to sessionstore tab data sooner **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
let startedTest = false;
|
||||
|
||||
// wasLoaded will be used to keep track of tabs that have already had SSTabRestoring
|
||||
// fired for them.
|
||||
let wasLoaded = { };
|
||||
let restoringTabsCount = 0;
|
||||
let uniq2 = { };
|
||||
let uniq2Count = 0;
|
||||
let state = { windows: [{ tabs: [] }] };
|
||||
// We're going to put a bunch of tabs into this state
|
||||
for (let i = 0; i < NUM_TABS; i++) {
|
||||
let uniq = r();
|
||||
let tabData = {
|
||||
entries: [{ url: "http://example.com/#" + i }],
|
||||
extData: { "uniq": uniq }
|
||||
};
|
||||
state.windows[0].tabs.push(tabData);
|
||||
wasLoaded[uniq] = false;
|
||||
}
|
||||
|
||||
|
||||
function onSSTabRestoring(aEvent) {
|
||||
restoringTabsCount++;
|
||||
let uniq = ss.getTabValue(aEvent.originalTarget, "uniq");
|
||||
wasLoaded[uniq] = true;
|
||||
|
||||
// On the first SSTabRestoring we're going to run the the real test.
|
||||
// We'll keep this listener around so we can keep marking tabs as restored.
|
||||
if (restoringTabsCount == 1)
|
||||
onFirstSSTabRestoring();
|
||||
else if (restoringTabsCount == NUM_TABS)
|
||||
onLastSSTabRestoring();
|
||||
}
|
||||
|
||||
// This does the actual testing. SSTabRestoring should be firing on tabs from
|
||||
// left to right, so we're going to start with the rightmost tab.
|
||||
function onFirstSSTabRestoring() {
|
||||
info("onFirstSSTabRestoring...");
|
||||
for (let i = gBrowser.tabs.length - 1; i >= 0; i--) {
|
||||
let tab = gBrowser.tabs[i];
|
||||
let actualUniq = ss.getTabValue(tab, "uniq");
|
||||
let expectedUniq = state.windows[0].tabs[i].extData["uniq"];
|
||||
|
||||
if (wasLoaded[actualUniq]) {
|
||||
info("tab " + i + ": already restored");
|
||||
continue;
|
||||
}
|
||||
is(actualUniq, expectedUniq, "tab " + i + ": extData was correct");
|
||||
|
||||
// Now we're going to set a piece of data back on the tab so it can be read
|
||||
// to test setting a value "early".
|
||||
uniq2[actualUniq] = r();
|
||||
ss.setTabValue(tab, "uniq2", uniq2[actualUniq]);
|
||||
// This will be used in the final comparison to make sure we checked the
|
||||
// same number as we set.
|
||||
uniq2Count++;
|
||||
}
|
||||
}
|
||||
|
||||
function onLastSSTabRestoring() {
|
||||
let checked = 0;
|
||||
for (let i = 0; i < gBrowser.tabs.length; i++) {
|
||||
let tab = gBrowser.tabs[i];
|
||||
let uniq = ss.getTabValue(tab, "uniq");
|
||||
|
||||
// Look to see if we set a uniq2 value for this uniq value
|
||||
if (uniq in uniq2) {
|
||||
is(ss.getTabValue(tab, "uniq2"), uniq2[uniq], "tab " + i + " has correct uniq2 value");
|
||||
checked++;
|
||||
}
|
||||
}
|
||||
is(checked, uniq2Count, "checked the same number of uniq2 as we set");
|
||||
cleanup();
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
// remove the event listener and clean up before finishing
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring, false);
|
||||
// Put this in an executeSoon because we still haven't called restoreNextTab
|
||||
// in sessionstore for the last tab (we'll call it after this). We end up
|
||||
// trying to restore the tab (since we then add a closed tab to the array).
|
||||
executeSoon(function() {
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
});
|
||||
}
|
||||
|
||||
// Add the event listener
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring, false);
|
||||
// Restore state
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
// Helper function to create a random value
|
||||
function r() {
|
||||
return "" + Date.now() + Math.random();
|
||||
}
|
||||
|
@ -394,7 +394,7 @@ Bookmark.prototype = {
|
||||
onEndUpdateBatch : function bm_oeub() {
|
||||
},
|
||||
|
||||
onItemAdded : function bm_oia(aId, aFolder, aIndex) {
|
||||
onItemAdded : function bm_oia(aId, aFolder, aIndex, aItemType, aURI) {
|
||||
// bookmark object doesn't exist at this point
|
||||
},
|
||||
|
||||
@ -547,7 +547,7 @@ BookmarkFolder.prototype = {
|
||||
onEndUpdateBatch : function bmf_oeub() {
|
||||
},
|
||||
|
||||
onItemAdded : function bmf_oia(aId, aFolder, aIndex) {
|
||||
onItemAdded : function bmf_oia(aId, aFolder, aIndex, aItemType, aURI) {
|
||||
// handle root folder events
|
||||
if (!this._parent)
|
||||
this._events.dispatch("add", aId);
|
||||
|
@ -1,26 +0,0 @@
|
||||
<!ENTITY find.label "Search:">
|
||||
<!ENTITY find.accesskey "S">
|
||||
<!ENTITY expand.label "Expand">
|
||||
<!ENTITY expand.accesskey "E">
|
||||
<!ENTITY collapse.label "Collapse">
|
||||
<!ENTITY collapse.accesskey "C">
|
||||
<!ENTITY byDate.label "By Date">
|
||||
<!ENTITY byDate.accesskey "D">
|
||||
<!ENTITY bySite.label "By Site">
|
||||
<!ENTITY bySite.accesskey "S">
|
||||
<!ENTITY view.label "View">
|
||||
<!ENTITY view.accesskey "w">
|
||||
<!ENTITY byMostVisited.label "By Most Visited">
|
||||
<!ENTITY byMostVisited.accesskey "V">
|
||||
<!ENTITY byLastVisited.label "By Last Visited">
|
||||
<!ENTITY byLastVisited.accesskey "L">
|
||||
<!ENTITY byDayAndSite.label "By Date and Site">
|
||||
<!ENTITY byDayAndSite.accesskey "t">
|
||||
<!ENTITY openLinkInWindow.label "Open">
|
||||
<!ENTITY openLinkInWindow.accesskey "O">
|
||||
<!ENTITY openInNewTab.label "Open in New Tab">
|
||||
<!ENTITY openInNewTab.accesskey "T">
|
||||
<!ENTITY openInNewWindow.label "Open in New Window">
|
||||
<!ENTITY openInNewWindow.accesskey "W">
|
||||
<!ENTITY copyLink.label "Copy Link Location">
|
||||
<!ENTITY copyLink.accesskey "C">
|
@ -94,6 +94,8 @@
|
||||
|
||||
<!ENTITY search.label "Search:">
|
||||
<!ENTITY search.accesskey "S">
|
||||
|
||||
<!ENTITY search.in.label "Search in:">
|
||||
<!ENTITY search.scopeFolder.label "Selected Folder">
|
||||
<!ENTITY search.scopeFolder.accesskey "r">
|
||||
<!ENTITY search.scopeBookmarks.label "Bookmarks">
|
||||
@ -123,3 +125,18 @@
|
||||
<!ENTITY detailsPane.less.accesskey "e">
|
||||
<!ENTITY detailsPane.noPreviewAvailable.label "Preview">
|
||||
<!ENTITY detailsPane.selectAnItemText.description "Select an item to view and edit its properties">
|
||||
|
||||
<!ENTITY find.label "Search:">
|
||||
<!ENTITY find.accesskey "S">
|
||||
<!ENTITY view.label "View">
|
||||
<!ENTITY view.accesskey "w">
|
||||
<!ENTITY byDate.label "By Date">
|
||||
<!ENTITY byDate.accesskey "D">
|
||||
<!ENTITY bySite.label "By Site">
|
||||
<!ENTITY bySite.accesskey "S">
|
||||
<!ENTITY byMostVisited.label "By Most Visited">
|
||||
<!ENTITY byMostVisited.accesskey "V">
|
||||
<!ENTITY byLastVisited.label "By Last Visited">
|
||||
<!ENTITY byLastVisited.accesskey "L">
|
||||
<!ENTITY byDayAndSite.label "By Date and Site">
|
||||
<!ENTITY byDayAndSite.accesskey "t">
|
||||
|
@ -45,7 +45,6 @@
|
||||
#endif
|
||||
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
|
||||
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
|
||||
locale/browser/history/history.dtd (%chrome/browser/history/history.dtd)
|
||||
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
|
||||
locale/browser/migration/migration.properties (%chrome/browser/migration/migration.properties)
|
||||
locale/browser/preferences/advanced.dtd (%chrome/browser/preferences/advanced.dtd)
|
||||
|
@ -46,6 +46,7 @@ ro
|
||||
ru
|
||||
sk
|
||||
son
|
||||
sq
|
||||
sv-SE
|
||||
tr
|
||||
uk
|
||||
|
@ -474,11 +474,15 @@ menuitem:not([type]) {
|
||||
|
||||
#bookmarksToolbarFolderMenu,
|
||||
#BMB_bookmarksToolbar {
|
||||
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
|
||||
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
|
||||
}
|
||||
|
||||
#BMB_bookmarkThisPage {
|
||||
list-style-image: url("chrome://browser/skin/places/starPage.png");
|
||||
}
|
||||
|
||||
#BMB_unsortedBookmarks {
|
||||
list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
|
||||
list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
|
||||
}
|
||||
|
||||
#menu_openDownloads {
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
%define customToolbarColor hsl(214,44%,87%)
|
||||
%define glassToolbarBorderColor rgb(40%,40%,40%)
|
||||
%define glassActiveBorderColor rgb(37, 44, 51)
|
||||
%define glassInactiveBorderColor rgb(102, 102, 102)
|
||||
|
||||
@media all and (-moz-windows-default-theme) {
|
||||
#navigator-toolbox > toolbar:not(:-moz-lwtheme) {
|
||||
@ -31,6 +33,12 @@
|
||||
0 0 2px 1px rgba(255,255,255,.25) inset;
|
||||
}
|
||||
|
||||
#main-window[privatebrowsingmode=temporary] #appmenu-button:not(:-moz-window-inactive) {
|
||||
-moz-border-left-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
|
||||
-moz-border-bottom-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
|
||||
-moz-border-right-colors: rgba(255,255,255,.5) rgba(43,8,65,.9);
|
||||
}
|
||||
|
||||
#appmenu-button:-moz-window-inactive {
|
||||
-moz-border-left-colors: rgba(255,255,255,.4) rgba(0,0,0,.5);
|
||||
-moz-border-bottom-colors: rgba(255,255,255,.4) rgba(0,0,0,.5);
|
||||
@ -85,6 +93,24 @@
|
||||
margin-top: -7px;
|
||||
}
|
||||
|
||||
/* Artificially draw window borders that are covered by lwtheme, see bug 591930. */
|
||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content:-moz-lwtheme {
|
||||
border-top: 2px solid;
|
||||
-moz-border-top-colors: @glassActiveBorderColor@ rgba(255,255,255,.6);
|
||||
}
|
||||
|
||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content:-moz-lwtheme:-moz-window-inactive {
|
||||
-moz-border-top-colors: @glassInactiveBorderColor@ rgba(255,255,255,.6);
|
||||
}
|
||||
|
||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #appmenu-button-container:-moz-lwtheme {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
#main-window[sizemode="normal"] > #titlebar > #titlebar-content > #titlebar-buttonbox:-moz-lwtheme {
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
#main-window:not(:-moz-lwtheme)[inFullscreen="true"] {
|
||||
-moz-appearance: none;
|
||||
background-color: #556;
|
||||
|
@ -126,6 +126,11 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#main-window[privatebrowsingmode=temporary] #appmenu-button:not(:-moz-window-inactive) {
|
||||
background-image: -moz-linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%);
|
||||
border-color: rgba(43,8,65,.9);
|
||||
}
|
||||
|
||||
#appmenu-button:-moz-window-inactive {
|
||||
background-image: none;
|
||||
border-color: rgba(0,0,0,.4);
|
||||
@ -141,6 +146,16 @@
|
||||
0 -1px 0 rgba(250,234,169,.5) inset;
|
||||
}
|
||||
|
||||
#main-window[privatebrowsingmode=temporary] #appmenu-button:hover:not(:active):not([open]) {
|
||||
background-image: -moz-radial-gradient(center bottom, farthest-side, rgba(240,193,255,.5) 10%, rgba(240,193,255,0) 70%),
|
||||
-moz-radial-gradient(center bottom, farthest-side, rgb(192,81,247), rgba(236,172,255,0)),
|
||||
-moz-linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%);
|
||||
border-color: rgba(43,8,65,.9);
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,.1) inset,
|
||||
0 0 2px 1px rgba(240,193,255,.7) inset,
|
||||
0 -1px 0 rgba(240,193,255,.5) inset;
|
||||
}
|
||||
|
||||
#appmenu-button:hover:active,
|
||||
#appmenu-button[open] {
|
||||
background-image: -moz-linear-gradient(rgb(246,170,69), rgb(209,74,0) 95%);
|
||||
@ -149,6 +164,11 @@
|
||||
0 1px 1px rgba(0,0,0,.2) inset;
|
||||
}
|
||||
|
||||
#main-window[privatebrowsingmode=temporary] #appmenu-button:hover:active,
|
||||
#main-window[privatebrowsingmode=temporary] #appmenu-button[open] {
|
||||
background-image: -moz-linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%);
|
||||
}
|
||||
|
||||
#appmenu-button > .button-box {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
|
@ -351,6 +351,7 @@ user_pref("layout.debug.enable_data_xbl", true);
|
||||
user_pref("browser.EULA.override", true);
|
||||
user_pref("javascript.options.tracejit.content", true);
|
||||
user_pref("javascript.options.methodjit.content", true);
|
||||
user_pref("javascript.options.jitprofiling.content", true);
|
||||
user_pref("gfx.color_management.force_srgb", true);
|
||||
user_pref("network.manage-offline-status", false);
|
||||
user_pref("test.mousescroll", true);
|
||||
|
31
configure.in
31
configure.in
@ -5006,8 +5006,8 @@ BUILD_CTYPES=1
|
||||
XPC_IDISPATCH_SUPPORT=
|
||||
|
||||
|
||||
case "$target_os" in
|
||||
darwin*|*wince*|*winmo*)
|
||||
case "${target}" in
|
||||
*android*|*darwin*|*wince*|*winmo*)
|
||||
ACCESSIBILITY=
|
||||
;;
|
||||
*)
|
||||
@ -8512,31 +8512,6 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
AC_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
|
||||
fi
|
||||
|
||||
AC_TRY_COMPILE([#include <ddraw.h>], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=)
|
||||
if test -z "$HAS_DDRAW"; then
|
||||
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
|
||||
DDRAW_SURFACE_FEATURE=
|
||||
else
|
||||
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
|
||||
fi
|
||||
|
||||
if test -z "$OGLES_SDK_DIR"; then
|
||||
OGLES_SURFACE_FEATURE=
|
||||
else
|
||||
AC_TRY_COMPILE([
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
], [ EGLDisplay _cairo_ddraw_egl_dpy = EGL_NO_DISPLAY;], HAS_OGLES=1, HAS_OGLES=)
|
||||
if test -z "$HAS_OGLES"; then
|
||||
AC_MSG_WARN([OpenGL ES2 headers not found, disabling OpenGL acceleration surfaces.])
|
||||
OGLES_SURFACE_FEATURE=
|
||||
else
|
||||
OGLES_SURFACE_FEATURE="#define CAIRO_DDRAW_USE_GL 1"
|
||||
fi
|
||||
fi
|
||||
|
||||
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
||||
fi
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
|
||||
@ -8581,8 +8556,6 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
AC_SUBST(QUARTZ_IMAGE_SURFACE_FEATURE)
|
||||
AC_SUBST(XCB_SURFACE_FEATURE)
|
||||
AC_SUBST(WIN32_SURFACE_FEATURE)
|
||||
AC_SUBST(DDRAW_SURFACE_FEATURE)
|
||||
AC_SUBST(OGLES_SURFACE_FEATURE)
|
||||
AC_SUBST(OS2_SURFACE_FEATURE)
|
||||
AC_SUBST(BEOS_SURFACE_FEATURE)
|
||||
AC_SUBST(DIRECTFB_SURFACE_FEATURE)
|
||||
|
@ -51,7 +51,7 @@ interface nsIDOMNode;
|
||||
interface nsISelection;
|
||||
interface nsISelectionDisplay;
|
||||
|
||||
[scriptable, uuid(bc5795ab-bcb5-448b-b3c7-a111bead7c26)]
|
||||
[scriptable, uuid(ff11fa25-788f-444f-8f69-dcdf14348fb3)]
|
||||
interface nsISelectionController : nsISelectionDisplay
|
||||
{
|
||||
const short SELECTION_NONE=0;
|
||||
@ -94,20 +94,27 @@ interface nsISelectionController : nsISelectionDisplay
|
||||
*/
|
||||
nsISelection getSelection(in short type);
|
||||
|
||||
const short SCROLL_SYNCHRONOUS = 1<<1;
|
||||
const short SCROLL_FIRST_ANCESTOR_ONLY = 1<<2;
|
||||
|
||||
/**
|
||||
* ScrollSelectionIntoView scrolls a region of the selection,
|
||||
* so that it is visible in the scrolled view.
|
||||
*
|
||||
* @param aType the selection to scroll into view. //SelectionType
|
||||
* @param aRegion the region inside the selection to scroll into view. //SelectionRegion
|
||||
* @param aIsSynchronous when true, scrolls the selection into view
|
||||
* before returning. If false, posts a request which is processed
|
||||
* @param aFlags the scroll flags. Valid bits include:
|
||||
* SCROLL_SYNCHRONOUS: when set, scrolls the selection into view
|
||||
* before returning. If not set, posts a request which is processed
|
||||
* at some point after the method returns.
|
||||
* SCROLL_FIRST_ANCESTOR_ONLY: if set, only the first ancestor will be scrolled
|
||||
* into view.
|
||||
*
|
||||
* Note that if isSynchronous is true, then this might flush the pending
|
||||
* reflow. It's dangerous for some objects. See bug 418470 comment 12.
|
||||
*/
|
||||
void scrollSelectionIntoView(in short type, in short region, in boolean isSynchronous);
|
||||
void scrollSelectionIntoView(in short type, in short region, in short flags);
|
||||
|
||||
/**
|
||||
* RepaintSelection repaints the selection specified by aType.
|
||||
*
|
||||
|
@ -380,8 +380,7 @@ CSPRep.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates string representation of the policy. Should be fairly similar
|
||||
* to the original.
|
||||
* Generates canonical string representation of the policy.
|
||||
*/
|
||||
toString:
|
||||
function csp_toString() {
|
||||
@ -607,8 +606,7 @@ CSPSourceList.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates string representation of the Source List.
|
||||
* Should be fairly similar to the original.
|
||||
* Generates canonical string representation of the Source List.
|
||||
*/
|
||||
toString:
|
||||
function() {
|
||||
@ -639,7 +637,7 @@ CSPSourceList.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes a new instance that resembles this object.
|
||||
* Makes a new deep copy of this object.
|
||||
* @returns
|
||||
* a new CSPSourceList
|
||||
*/
|
||||
@ -951,7 +949,7 @@ CSPSource.fromString = function(aStr, self, enforceSelfChecks) {
|
||||
// Allow scheme-only sources! These default to wildcard host/port,
|
||||
// especially since host and port don't always matter.
|
||||
// Example: "javascript:" and "data:"
|
||||
if (!sObj._host) sObj._host = "*";
|
||||
if (!sObj._host) sObj._host = CSPHost.fromString("*");
|
||||
if (!sObj._port) sObj._port = "*";
|
||||
} else {
|
||||
// some host was defined.
|
||||
@ -1050,8 +1048,7 @@ CSPSource.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates string representation of the Source.
|
||||
* Should be fairly similar to the original.
|
||||
* Generates canonical string representation of the Source.
|
||||
*/
|
||||
toString:
|
||||
function() {
|
||||
@ -1069,7 +1066,7 @@ CSPSource.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes a new instance that resembles this object.
|
||||
* Makes a new deep copy of this object.
|
||||
* @returns
|
||||
* a new CSPSource
|
||||
*/
|
||||
@ -1172,13 +1169,28 @@ CSPSource.prototype = {
|
||||
return null;
|
||||
}
|
||||
|
||||
// NOTE: Both sources must have a host, if they don't, something funny is
|
||||
// going on. The fromString() factory method should have set the host to
|
||||
// * if there's no host specified in the input. Regardless, if a host is
|
||||
// not present either the scheme is hostless or any host should be allowed.
|
||||
// This means we can use the other source's host as the more restrictive
|
||||
// host expression, or if neither are present, we can use "*", but the
|
||||
// error should still be reported.
|
||||
|
||||
// host
|
||||
if (!this._host)
|
||||
newSource._host = that._host;
|
||||
else if (!that._host)
|
||||
newSource._host = this._host;
|
||||
else // both this and that have hosts
|
||||
if (this._host && that._host) {
|
||||
newSource._host = this._host.intersectWith(that._host);
|
||||
} else if (this._host) {
|
||||
CSPError("intersecting source with undefined host: " + that.toString());
|
||||
newSource._host = this._host.clone();
|
||||
} else if (that._host) {
|
||||
CSPError("intersecting source with undefined host: " + this.toString());
|
||||
newSource._host = that._host.clone();
|
||||
} else {
|
||||
CSPError("intersecting two sources with undefined hosts: " +
|
||||
this.toString() + " and " + that.toString());
|
||||
newSource._host = CSPHost.fromString("*");
|
||||
}
|
||||
|
||||
return newSource;
|
||||
},
|
||||
@ -1266,8 +1278,7 @@ CSPHost.fromString = function(aStr) {
|
||||
|
||||
CSPHost.prototype = {
|
||||
/**
|
||||
* Generates string representation of the Source.
|
||||
* Should be fairly similar to the original.
|
||||
* Generates canonical string representation of the Host.
|
||||
*/
|
||||
toString:
|
||||
function() {
|
||||
@ -1275,7 +1286,7 @@ CSPHost.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes a new instance that resembles this object.
|
||||
* Makes a new deep copy of this object.
|
||||
* @returns
|
||||
* a new CSPHost
|
||||
*/
|
||||
@ -1297,7 +1308,7 @@ CSPHost.prototype = {
|
||||
*/
|
||||
permits:
|
||||
function(aHost) {
|
||||
if (!aHost) return false;
|
||||
if (!aHost) aHost = CSPHost.fromString("*");
|
||||
|
||||
if (!(aHost instanceof CSPHost)) {
|
||||
// -- compare CSPHost to String
|
||||
|
@ -5854,7 +5854,7 @@ CloneSimpleValues(JSContext* cx,
|
||||
}
|
||||
|
||||
// Security wrapped objects are not allowed either.
|
||||
if (obj->getClass()->ext.wrappedObject)
|
||||
if (obj->isWrapper() && !obj->getClass()->ext.innerObject)
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
|
||||
// See if this JSObject is backed by some C++ object. If it is then we assume
|
||||
|
@ -3568,18 +3568,18 @@ nsINode::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 childCount = aChildArray.ChildCount();
|
||||
NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// The id-handling code, and in the future possibly other code, need to
|
||||
// react to unexpected attribute changes.
|
||||
nsMutationGuard::DidMutate();
|
||||
|
||||
PRBool isAppend = (aIndex == childCount);
|
||||
|
||||
// Do this before checking the child-count since this could cause mutations
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
mozAutoDocUpdate updateBatch(doc, UPDATE_CONTENT_MODEL, aNotify);
|
||||
|
||||
PRUint32 childCount = aChildArray.ChildCount();
|
||||
NS_ENSURE_TRUE(aIndex <= childCount, NS_ERROR_ILLEGAL_VALUE);
|
||||
PRBool isAppend = (aIndex == childCount);
|
||||
|
||||
rv = aChildArray.InsertChildAt(aKid, aIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aIndex == 0) {
|
||||
@ -4019,6 +4019,8 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
|
||||
nsresult res = NS_OK;
|
||||
PRInt32 insPos;
|
||||
|
||||
mozAutoDocConditionalContentUpdateBatch batch(GetCurrentDoc(), PR_TRUE);
|
||||
|
||||
// Figure out which index to insert at
|
||||
if (aRefChild) {
|
||||
insPos = IndexOf(aRefChild);
|
||||
@ -4080,11 +4082,6 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
|
||||
}
|
||||
}
|
||||
|
||||
// We want an update batch when we expect several mutations to be performed,
|
||||
// which is when we're replacing a node, or when we're inserting a fragment.
|
||||
mozAutoDocConditionalContentUpdateBatch batch(GetCurrentDoc(),
|
||||
aReplace || nodeType == nsIDOMNode::DOCUMENT_FRAGMENT_NODE);
|
||||
|
||||
// If we're replacing
|
||||
if (aReplace) {
|
||||
refContent = GetChildAt(insPos + 1);
|
||||
@ -5328,7 +5325,7 @@ nsGenericElement::PostHandleEventForLinks(nsEventChainPostVisitor& aVisitor)
|
||||
|
||||
nsIEventStateManager* esm =
|
||||
aVisitor.mPresContext->EventStateManager();
|
||||
nsEventStateManager::SetGlobalActiveContent(
|
||||
nsEventStateManager::SetActiveManager(
|
||||
static_cast<nsEventStateManager*>(esm), this);
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,13 @@
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"/>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/x-javascript">
|
||||
var bodyOnLoad = false;
|
||||
function checkOnLoad()
|
||||
function onLoadFired()
|
||||
{
|
||||
ok(bodyOnLoad, "Body onload event should fire");
|
||||
ok(true, "Body onload event should fire");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
setTimeout(checkOnLoad, 500);
|
||||
</script>
|
||||
</head>
|
||||
<body onload="bodyOnLoad = true;"/>
|
||||
<body onload="onLoadFired();"/>
|
||||
</html>
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
//load('CSPUtils.jsm');
|
||||
Components.utils.import('resource://gre/modules/CSPUtils.jsm');
|
||||
Components.utils.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
||||
// load the HTTP server
|
||||
do_load_httpd_js();
|
||||
@ -190,6 +191,7 @@ test(
|
||||
|
||||
//"funny characters (#) should not work for host.");
|
||||
do_check_eq(null, CSPSource.fromString("a#2-c.com"));
|
||||
|
||||
//print(" --- Stop ignoring errors that print ---\n");
|
||||
|
||||
//"failed to parse host with port.");
|
||||
@ -229,6 +231,16 @@ test(
|
||||
do_check_true(src.permits("https://foobar.com"));
|
||||
//"src should reject other hosts"
|
||||
do_check_false(src.permits("https://a.com"));
|
||||
|
||||
src = CSPSource.create("javascript:", "https://foobar.com:443");
|
||||
//"hostless schemes should be parseable."
|
||||
var aUri = NetUtil.newURI("javascript:alert('foo');");
|
||||
do_check_true(src.permits(aUri));
|
||||
//"src should reject other hosts"
|
||||
do_check_false(src.permits("https://a.com"));
|
||||
//"nothing else should be allowed"
|
||||
do_check_false(src.permits("https://foobar.com"));
|
||||
|
||||
});
|
||||
|
||||
///////////////////// Test the source list //////////////////////
|
||||
|
@ -53,9 +53,11 @@ public:
|
||||
DocumentRendererChild();
|
||||
virtual ~DocumentRendererChild();
|
||||
|
||||
bool RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h,
|
||||
const nsString& bgcolor, const PRUint32& flags, const PRBool& flush,
|
||||
PRUint32& _width, PRUint32& _height, nsCString& data);
|
||||
bool RenderDocument(nsIDOMWindow *window,
|
||||
const nsRect& documentRect, const gfxMatrix& transform,
|
||||
const nsString& bgcolor,
|
||||
PRUint32 renderFlags, PRBool flushLayout,
|
||||
const nsIntSize& renderSize, nsCString& data);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -54,10 +54,10 @@ public:
|
||||
|
||||
void SetCanvasContext(nsICanvasRenderingContextInternal* aCanvas,
|
||||
gfxContext* ctx);
|
||||
void DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
|
||||
void DrawToCanvas(const nsIntSize& renderedSize,
|
||||
const nsCString& aData);
|
||||
|
||||
virtual bool Recv__delete__(const PRUint32& w, const PRUint32& h,
|
||||
virtual bool Recv__delete__(const nsIntSize& renderedSize,
|
||||
const nsCString& data);
|
||||
|
||||
private:
|
||||
|
@ -120,16 +120,6 @@ public:
|
||||
// anything into this canvas before changing the shmem state, it will be
|
||||
// lost.
|
||||
NS_IMETHOD SetIsIPC(PRBool isIPC) = 0;
|
||||
|
||||
// Swap this back buffer with the front, and copy its contents to the new
|
||||
// back. x, y, w, and h specify the area of |back| that is dirty.
|
||||
NS_IMETHOD Swap(mozilla::ipc::Shmem& back,
|
||||
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) = 0;
|
||||
|
||||
// Sync back and front buffer, move ownership of back buffer to parent
|
||||
NS_IMETHOD Swap(PRUint32 nativeID,
|
||||
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h) = 0;
|
||||
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsICanvasRenderingContextInternal,
|
||||
|
@ -99,11 +99,16 @@ FlushLayoutForTree(nsIDOMWindow* aWindow)
|
||||
}
|
||||
|
||||
bool
|
||||
DocumentRendererChild::RenderDocument(nsIDOMWindow *window, const PRInt32& x, const PRInt32& y, const PRInt32& w, const PRInt32& h,
|
||||
const nsString& aBGColor, const PRUint32& flags, const PRBool& flush,
|
||||
PRUint32& _width, PRUint32& _height, nsCString& data)
|
||||
DocumentRendererChild::RenderDocument(nsIDOMWindow *window,
|
||||
const nsRect& documentRect,
|
||||
const gfxMatrix& transform,
|
||||
const nsString& bgcolor,
|
||||
PRUint32 renderFlags,
|
||||
PRBool flushLayout,
|
||||
const nsIntSize& renderSize,
|
||||
nsCString& data)
|
||||
{
|
||||
if (flush)
|
||||
if (flushLayout)
|
||||
FlushLayoutForTree(window);
|
||||
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
@ -119,26 +124,25 @@ DocumentRendererChild::RenderDocument(nsIDOMWindow *window, const PRInt32& x, co
|
||||
|
||||
nscolor bgColor;
|
||||
nsCSSParser parser;
|
||||
nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor),
|
||||
nsresult rv = parser.ParseColorString(PromiseFlatString(bgcolor),
|
||||
nsnull, 0, &bgColor);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
|
||||
nsRect r(x, y, w, h);
|
||||
|
||||
_width = nsPresContext::AppUnitsToIntCSSPixels(w);
|
||||
_height = nsPresContext::AppUnitsToIntCSSPixels(h);
|
||||
|
||||
// Draw directly into the output array.
|
||||
data.SetLength(_width * _height * 4);
|
||||
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(reinterpret_cast<PRUint8*>(const_cast<char*>(data.get())),
|
||||
gfxIntSize(_width, _height),
|
||||
4 * _width, gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
data.SetLength(renderSize.width * renderSize.height * 4);
|
||||
|
||||
presShell->RenderDocument(r, flags, bgColor, ctx);
|
||||
nsRefPtr<gfxImageSurface> surf =
|
||||
new gfxImageSurface(reinterpret_cast<uint8*>(data.BeginWriting()),
|
||||
gfxIntSize(renderSize.width, renderSize.height),
|
||||
4 * renderSize.width,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
ctx->SetMatrix(transform);
|
||||
|
||||
presShell->RenderDocument(documentRect, renderFlags, bgColor, ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1,185 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Fennec Electrolysis.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Nokia.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifdef MOZ_WIDGET_QT
|
||||
#include <QX11Info>
|
||||
#define DISPLAY QX11Info::display
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
#include <gdk/gdkx.h>
|
||||
#define DISPLAY GDK_DISPLAY
|
||||
#endif
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsColor.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "mozilla/ipc/DocumentRendererNativeIDChild.h"
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#include "gfxXlibSurface.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
DocumentRendererNativeIDChild::DocumentRendererNativeIDChild()
|
||||
{}
|
||||
|
||||
DocumentRendererNativeIDChild::~DocumentRendererNativeIDChild()
|
||||
{}
|
||||
|
||||
static void
|
||||
FlushLayoutForTree(nsIDOMWindow* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
|
||||
if (!piWin)
|
||||
return;
|
||||
|
||||
// Note that because FlushPendingNotifications flushes parents, this
|
||||
// is O(N^2) in docshell tree depth. However, the docshell tree is
|
||||
// usually pretty shallow.
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeNode> node =
|
||||
do_QueryInterface(piWin->GetDocShell());
|
||||
if (node) {
|
||||
PRInt32 i = 0, i_end;
|
||||
node->GetChildCount(&i_end);
|
||||
for (; i < i_end; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
node->GetChildAt(i, getter_AddRefs(item));
|
||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
|
||||
if (win) {
|
||||
FlushLayoutForTree(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DocumentRendererNativeIDChild::RenderDocument(nsIDOMWindow* window, const PRInt32& x,
|
||||
const PRInt32& y, const PRInt32& w,
|
||||
const PRInt32& h, const nsString& aBGColor,
|
||||
const PRUint32& flags, const PRBool& flush,
|
||||
const gfxMatrix& aMatrix,
|
||||
const PRInt32& nativeID)
|
||||
{
|
||||
if (!nativeID)
|
||||
return false;
|
||||
|
||||
if (flush)
|
||||
FlushLayoutForTree(window);
|
||||
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
|
||||
if (win) {
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
}
|
||||
if (!presContext)
|
||||
return false;
|
||||
|
||||
nscolor bgColor;
|
||||
nsCSSParser parser;
|
||||
nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor), nsnull, 0, &bgColor);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
|
||||
nsRect r(x, y, w, h);
|
||||
|
||||
// Draw directly into the output array.
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
#ifdef MOZ_X11
|
||||
// Initialize gfxXlibSurface from native XID by using toolkit functionality
|
||||
// Would be nice to have gfxXlibSurface(nativeID) implementation
|
||||
Display* dpy = DISPLAY();
|
||||
int depth = DefaultDepth(dpy, DefaultScreen(dpy));
|
||||
XVisualInfo vinfo;
|
||||
int foundVisual = XMatchVisualInfo(dpy,
|
||||
DefaultScreen(dpy),
|
||||
depth,
|
||||
TrueColor,
|
||||
&vinfo);
|
||||
if (!foundVisual)
|
||||
return false;
|
||||
|
||||
surf = new gfxXlibSurface(dpy, nativeID, vinfo.visual);
|
||||
#else
|
||||
NS_ERROR("NativeID handler not implemented for your platform");
|
||||
#endif
|
||||
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
ctx->SetMatrix(aMatrix);
|
||||
|
||||
presShell->RenderDocument(r, flags, bgColor, ctx);
|
||||
#ifdef MOZ_X11
|
||||
// We are about to pass this buffer across process boundaries, and when we
|
||||
// try to read from the surface in the other process, we're not guaranteed
|
||||
// the drawing has actually happened, as the drawing commands might still
|
||||
// be queued. By syncing with X, we guarantee the drawing has finished
|
||||
// before we pass the buffer back.
|
||||
XSync(dpy, False);
|
||||
#endif
|
||||
return true;
|
||||
}
|
@ -53,33 +53,36 @@ void DocumentRendererParent::SetCanvasContext(nsICanvasRenderingContextInternal*
|
||||
mCanvasContext = ctx;
|
||||
}
|
||||
|
||||
void DocumentRendererParent::DrawToCanvas(PRUint32 aWidth, PRUint32 aHeight,
|
||||
void DocumentRendererParent::DrawToCanvas(const nsIntSize& aSize,
|
||||
const nsCString& aData)
|
||||
{
|
||||
if (!mCanvas || !mCanvasContext)
|
||||
return;
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(reinterpret_cast<PRUint8*>(const_cast<char*>(aData.Data())),
|
||||
gfxIntSize(aWidth, aHeight),
|
||||
aWidth * 4,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxImageSurface> surf =
|
||||
new gfxImageSurface(reinterpret_cast<uint8*>(const_cast<nsCString&>(aData).BeginWriting()),
|
||||
gfxIntSize(aSize.width, aSize.height),
|
||||
aSize.width * 4,
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxPattern> pat = new gfxPattern(surf);
|
||||
|
||||
gfxRect rect(gfxPoint(0, 0), gfxSize(aSize.width, aSize.height));
|
||||
mCanvasContext->NewPath();
|
||||
mCanvasContext->PixelSnappedRectangleAndSetPattern(gfxRect(0, 0, aWidth, aHeight), pat);
|
||||
mCanvasContext->PixelSnappedRectangleAndSetPattern(rect, pat);
|
||||
mCanvasContext->Fill();
|
||||
|
||||
// get rid of the pattern surface ref, because aData is very likely to go away shortly
|
||||
// get rid of the pattern surface ref, because aData is very
|
||||
// likely to go away shortly
|
||||
mCanvasContext->SetColor(gfxRGBA(1,1,1,1));
|
||||
|
||||
gfxRect damageRect = mCanvasContext->UserToDevice(gfxRect(0, 0, aWidth, aHeight));
|
||||
gfxRect damageRect = mCanvasContext->UserToDevice(rect);
|
||||
mCanvas->Redraw(damageRect);
|
||||
}
|
||||
|
||||
bool
|
||||
DocumentRendererParent::Recv__delete__(const PRUint32& w, const PRUint32& h,
|
||||
DocumentRendererParent::Recv__delete__(const nsIntSize& renderedSize,
|
||||
const nsCString& data)
|
||||
{
|
||||
DrawToCanvas(w, h, data);
|
||||
DrawToCanvas(renderedSize, data);
|
||||
return true;
|
||||
}
|
||||
|
@ -1,144 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Fennec Electrolysis.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxPattern.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsColor.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#ifdef MOZ_IPC
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/ipc/DocumentRendererShmemChild.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
DocumentRendererShmemChild::DocumentRendererShmemChild()
|
||||
{}
|
||||
|
||||
DocumentRendererShmemChild::~DocumentRendererShmemChild()
|
||||
{}
|
||||
|
||||
static void
|
||||
FlushLayoutForTree(nsIDOMWindow* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> piWin = do_QueryInterface(aWindow);
|
||||
if (!piWin)
|
||||
return;
|
||||
|
||||
// Note that because FlushPendingNotifications flushes parents, this
|
||||
// is O(N^2) in docshell tree depth. However, the docshell tree is
|
||||
// usually pretty shallow.
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
aWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
if (doc) {
|
||||
doc->FlushPendingNotifications(Flush_Layout);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeNode> node =
|
||||
do_QueryInterface(piWin->GetDocShell());
|
||||
if (node) {
|
||||
PRInt32 i = 0, i_end;
|
||||
node->GetChildCount(&i_end);
|
||||
for (; i < i_end; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
node->GetChildAt(i, getter_AddRefs(item));
|
||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(item);
|
||||
if (win) {
|
||||
FlushLayoutForTree(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DocumentRendererShmemChild::RenderDocument(nsIDOMWindow *window, const PRInt32& x,
|
||||
const PRInt32& y, const PRInt32& w,
|
||||
const PRInt32& h, const nsString& aBGColor,
|
||||
const PRUint32& flags, const PRBool& flush,
|
||||
const gfxMatrix& aMatrix,
|
||||
Shmem& data)
|
||||
{
|
||||
if (flush)
|
||||
FlushLayoutForTree(window);
|
||||
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
|
||||
if (win) {
|
||||
nsIDocShell* docshell = win->GetDocShell();
|
||||
if (docshell) {
|
||||
docshell->GetPresContext(getter_AddRefs(presContext));
|
||||
}
|
||||
}
|
||||
if (!presContext)
|
||||
return false;
|
||||
|
||||
nscolor bgColor;
|
||||
nsCSSParser parser;
|
||||
nsresult rv = parser.ParseColorString(PromiseFlatString(aBGColor), nsnull, 0, &bgColor);
|
||||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
|
||||
nsRect r(x, y, w, h);
|
||||
|
||||
// Draw directly into the output array.
|
||||
nsRefPtr<gfxASurface> surf = new gfxSharedImageSurface(data);
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(surf);
|
||||
ctx->SetMatrix(aMatrix);
|
||||
|
||||
presShell->RenderDocument(r, flags, bgColor, ctx);
|
||||
return true;
|
||||
}
|
@ -60,10 +60,6 @@ ifdef MOZ_IPC
|
||||
CPPSRCS += \
|
||||
DocumentRendererParent.cpp \
|
||||
DocumentRendererChild.cpp \
|
||||
DocumentRendererNativeIDParent.cpp \
|
||||
DocumentRendererNativeIDChild.cpp \
|
||||
DocumentRendererShmemParent.cpp \
|
||||
DocumentRendererShmemChild.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -103,9 +103,6 @@
|
||||
#include "gfxContext.h"
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#ifdef MOZ_IPC
|
||||
#include "gfxSharedImageSurface.h"
|
||||
#endif
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxFont.h"
|
||||
#include "gfxTextRunCache.h"
|
||||
@ -130,13 +127,8 @@
|
||||
# include <algorithm>
|
||||
# include "mozilla/dom/ContentParent.h"
|
||||
# include "mozilla/ipc/PDocumentRendererParent.h"
|
||||
# include "mozilla/ipc/PDocumentRendererShmemParent.h"
|
||||
# include "mozilla/ipc/PDocumentRendererNativeIDParent.h"
|
||||
# include "mozilla/dom/PBrowserParent.h"
|
||||
# include "mozilla/ipc/DocumentRendererParent.h"
|
||||
# include "mozilla/ipc/DocumentRendererShmemParent.h"
|
||||
# include "mozilla/ipc/DocumentRendererNativeIDParent.h"
|
||||
# include "mozilla/ipc/SharedMemorySysV.h"
|
||||
|
||||
// windows.h (included by chromium code) defines this, in its infinite wisdom
|
||||
# undef DrawText
|
||||
@ -144,10 +136,6 @@
|
||||
using namespace mozilla::ipc;
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#include "gfxXlibSurface.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
#include "nsSVGEffects.h"
|
||||
#endif
|
||||
@ -429,13 +417,6 @@ public:
|
||||
NS_IMETHOD SetIsIPC(PRBool isIPC);
|
||||
// this rect is in CSS pixels
|
||||
NS_IMETHOD Redraw(const gfxRect &r);
|
||||
// Swap this back buffer with the front, and copy its contents to the new back.
|
||||
// x, y, w, and h specify the area of |back| that is dirty.
|
||||
NS_IMETHOD Swap(mozilla::ipc::Shmem& back, PRInt32 x, PRInt32 y,
|
||||
PRInt32 w, PRInt32 h);
|
||||
NS_IMETHOD Swap(PRUint32 nativeID, PRInt32 x, PRInt32 y,
|
||||
PRInt32 w, PRInt32 h);
|
||||
|
||||
|
||||
// nsISupports interface + CC
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
@ -500,30 +481,13 @@ protected:
|
||||
*/
|
||||
gfxASurface::gfxImageFormat GetImageFormat() const;
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
/**
|
||||
* Sync data from mBackSurface to mSurface.
|
||||
*/
|
||||
nsresult Swap(const gfxRect& aRect);
|
||||
#endif
|
||||
|
||||
// Member vars
|
||||
PRInt32 mWidth, mHeight;
|
||||
PRPackedBool mValid;
|
||||
PRPackedBool mOpaque;
|
||||
PRPackedBool mResetLayer;
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
PRPackedBool mIPC;
|
||||
|
||||
// for rendering with NativeID protocol, we should track backbuffer ownership
|
||||
PRPackedBool mIsBackSurfaceReadable;
|
||||
// We always have a front buffer. We hand the mBackSurface to the other
|
||||
// process to render to,
|
||||
// and then sync data from mBackSurface to mSurface when it finishes.
|
||||
nsRefPtr<gfxASurface> mBackSurface;
|
||||
#endif
|
||||
|
||||
// the canvas element we're a context of
|
||||
nsCOMPtr<nsIDOMHTMLCanvasElement> mCanvasElement;
|
||||
nsHTMLCanvasElement *HTMLCanvasElement() {
|
||||
@ -814,18 +778,6 @@ protected:
|
||||
}
|
||||
|
||||
friend struct nsCanvasBidiProcessor;
|
||||
|
||||
private:
|
||||
#ifdef MOZ_IPC
|
||||
void DeallocShmemIfShared(nsRefPtr<gfxASurface> &aSurface) {
|
||||
ContentParent* allocator = ContentParent::GetSingleton(PR_FALSE);
|
||||
if (allocator && gfxSharedImageSurface::IsSharedImage(aSurface)) {
|
||||
Shmem mem = static_cast<gfxSharedImageSurface*>(aSurface.get())->GetShmem();
|
||||
allocator->DeallocShmem(mem);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsCanvasRenderingContext2D, nsIDOMCanvasRenderingContext2D)
|
||||
@ -871,9 +823,7 @@ NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
|
||||
|
||||
nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||
: mValid(PR_FALSE), mOpaque(PR_FALSE), mResetLayer(PR_TRUE)
|
||||
#ifdef MOZ_IPC
|
||||
, mIPC(PR_FALSE)
|
||||
#endif
|
||||
, mCanvasElement(nsnull)
|
||||
, mSaveCount(0), mIsEntireFrameInvalid(PR_FALSE), mInvalidateCount(0)
|
||||
, mLastStyle(STYLE_MAX), mStyleStack(20)
|
||||
@ -884,12 +834,6 @@ nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||
nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D()
|
||||
{
|
||||
Reset();
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
DeallocShmemIfShared(mBackSurface);
|
||||
mBackSurface = nsnull;
|
||||
#endif
|
||||
|
||||
sNumLivingContexts--;
|
||||
if (!sNumLivingContexts) {
|
||||
delete[] sUnpremultiplyTable;
|
||||
@ -902,10 +846,6 @@ nsCanvasRenderingContext2D::~nsCanvasRenderingContext2D()
|
||||
nsresult
|
||||
nsCanvasRenderingContext2D::Reset()
|
||||
{
|
||||
#ifdef MOZ_IPC
|
||||
DeallocShmemIfShared(mSurface);
|
||||
#endif
|
||||
|
||||
// only do this for non-docshell created contexts,
|
||||
// since those are the ones that we created a surface for
|
||||
if (mValid && !mDocShell)
|
||||
@ -1152,33 +1092,6 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
|
||||
if (surface && surface->CairoStatus() != 0)
|
||||
surface = NULL;
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
if (mIPC && surface) {
|
||||
#ifdef MOZ_X11
|
||||
if (surface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
mBackSurface =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, gfxASurface::ContentFromFormat(format));
|
||||
NS_ABORT_IF_FALSE(mBackSurface->GetType() ==
|
||||
gfxASurface::SurfaceTypeXlib, "need xlib surface");
|
||||
mIsBackSurfaceReadable = PR_TRUE;
|
||||
// Make sure that our XSurface created and synced properly
|
||||
XSync(static_cast<gfxXlibSurface*>(mBackSurface.get())->XDisplay(), False);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (surface->GetType() == gfxASurface::SurfaceTypeImage)
|
||||
format = static_cast<gfxImageSurface*>(surface.get())->Format();
|
||||
SharedMemory::SharedMemoryType shmtype = SharedMemory::TYPE_BASIC;
|
||||
#ifdef MOZ_HAVE_SHAREDMEMORYSYSV
|
||||
shmtype = SharedMemory::TYPE_SYSV;
|
||||
#endif
|
||||
ContentParent* allocator = ContentParent::GetSingleton();
|
||||
mBackSurface = new gfxSharedImageSurface();
|
||||
static_cast<gfxSharedImageSurface*>(mBackSurface.get())->Init(allocator, size, format, shmtype);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (surface) {
|
||||
if (gCanvasMemoryReporter == nsnull) {
|
||||
@ -1288,84 +1201,6 @@ nsCanvasRenderingContext2D::SetIsIPC(PRBool isIPC)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
nsresult
|
||||
nsCanvasRenderingContext2D::Swap(const gfxRect& aRect)
|
||||
{
|
||||
gfxContextPathAutoSaveRestore pathSR(mThebes);
|
||||
gfxContextAutoSaveRestore autoSR(mThebes);
|
||||
|
||||
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
mThebes->NewPath();
|
||||
mThebes->SetSource(mBackSurface);
|
||||
mThebes->Rectangle(aRect, PR_TRUE);
|
||||
mThebes->Clip();
|
||||
mThebes->Paint();
|
||||
|
||||
Redraw(aRect);
|
||||
|
||||
// Notify listeners that we've finished drawing
|
||||
nsCOMPtr<nsIContent> content =
|
||||
do_QueryInterface(static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement));
|
||||
nsIDocument* ownerDoc = nsnull;
|
||||
if (content)
|
||||
ownerDoc = content->GetOwnerDoc();
|
||||
|
||||
if (ownerDoc && mCanvasElement) {
|
||||
nsContentUtils::DispatchTrustedEvent(ownerDoc,
|
||||
static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
|
||||
NS_LITERAL_STRING("MozAsyncCanvasRender"),
|
||||
/* aCanBubble = */ PR_TRUE,
|
||||
/* aCancelable = */ PR_TRUE);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::Swap(mozilla::ipc::Shmem& aBack,
|
||||
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h)
|
||||
{
|
||||
#ifdef MOZ_IPC
|
||||
if (!gfxSharedImageSurface::IsSharedImage(mBackSurface))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRefPtr<gfxSharedImageSurface> aBackImage = new gfxSharedImageSurface(aBack);
|
||||
if (aBackImage->Data() != static_cast<gfxImageSurface*>(mBackSurface.get())->Data()) {
|
||||
NS_ERROR("Incoming back surface is not equal to our back surface");
|
||||
// Delete orphaned memory and return
|
||||
ContentParent* allocator = ContentParent::GetSingleton(PR_FALSE);
|
||||
if (allocator)
|
||||
allocator->DeallocShmem(aBack);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
Shmem& mem = static_cast<gfxSharedImageSurface*>(mBackSurface.get())->GetShmem();
|
||||
if (mem.IsReadable())
|
||||
NS_ERROR("Back surface readable before swap, this must not happen");
|
||||
|
||||
// Take mBackSurface shared memory ownership
|
||||
mem = aBack;
|
||||
return Swap(gfxRect(x, y, w, h));
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::Swap(PRUint32 nativeID,
|
||||
PRInt32 x, PRInt32 y, PRInt32 w, PRInt32 h)
|
||||
{
|
||||
#ifdef MOZ_IPC
|
||||
if (mIsBackSurfaceReadable)
|
||||
NS_ERROR("Back surface readable before swap, this must not happen");
|
||||
mIsBackSurfaceReadable = PR_TRUE;
|
||||
return Swap(gfxRect(x, y, w, h));
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::Render(gfxContext *ctx, gfxPattern::GraphicsFilter aFilter)
|
||||
{
|
||||
@ -3904,62 +3739,17 @@ nsCanvasRenderingContext2D::AsyncDrawXULElement(nsIDOMXULElement* aElem, float a
|
||||
renderDocFlags &= ~nsIPresShell::RENDER_IGNORE_VIEWPORT_SCROLLING;
|
||||
}
|
||||
|
||||
PRInt32 x = nsPresContext::CSSPixelsToAppUnits(aX),
|
||||
y = nsPresContext::CSSPixelsToAppUnits(aY),
|
||||
w = nsPresContext::CSSPixelsToAppUnits(aW),
|
||||
h = nsPresContext::CSSPixelsToAppUnits(aH);
|
||||
|
||||
nsRect rect(nsPresContext::CSSPixelsToAppUnits(aX),
|
||||
nsPresContext::CSSPixelsToAppUnits(aY),
|
||||
nsPresContext::CSSPixelsToAppUnits(aW),
|
||||
nsPresContext::CSSPixelsToAppUnits(aH));
|
||||
if (mIPC) {
|
||||
#ifdef MOZ_X11
|
||||
if (mBackSurface &&
|
||||
mBackSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
|
||||
|
||||
if (!mIsBackSurfaceReadable)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 nativeID = static_cast<gfxXlibSurface*>(mBackSurface.get())->XDrawable();
|
||||
mIsBackSurfaceReadable = PR_FALSE;
|
||||
PDocumentRendererNativeIDParent* pdocrender =
|
||||
child->SendPDocumentRendererNativeIDConstructor(x, y, w, h,
|
||||
nsString(aBGColor),
|
||||
renderDocFlags, flush,
|
||||
mThebes->CurrentMatrix(),
|
||||
nativeID);
|
||||
if (!pdocrender)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
DocumentRendererNativeIDParent* docrender =
|
||||
static_cast<DocumentRendererNativeIDParent *>(pdocrender);
|
||||
|
||||
docrender->SetCanvas(this);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (gfxSharedImageSurface::IsSharedImage(mBackSurface)) {
|
||||
Shmem& backmem = static_cast<gfxSharedImageSurface*>(mBackSurface.get())->GetShmem();
|
||||
if (!backmem.IsWritable())
|
||||
return NS_ERROR_FAILURE;
|
||||
PDocumentRendererShmemParent* pdocrender =
|
||||
child->SendPDocumentRendererShmemConstructor(x, y, w, h,
|
||||
nsString(aBGColor),
|
||||
renderDocFlags, flush,
|
||||
mThebes->CurrentMatrix(),
|
||||
backmem);
|
||||
|
||||
if (!pdocrender)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
DocumentRendererShmemParent* docrender =
|
||||
static_cast<DocumentRendererShmemParent*>(pdocrender);
|
||||
|
||||
docrender->SetCanvas(this);
|
||||
} else
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
PDocumentRendererParent *pdocrender =
|
||||
child->SendPDocumentRendererConstructor(x, y, w, h,
|
||||
child->SendPDocumentRendererConstructor(rect,
|
||||
mThebes->CurrentMatrix(),
|
||||
nsString(aBGColor),
|
||||
renderDocFlags, flush);
|
||||
renderDocFlags, flush,
|
||||
nsIntSize(mWidth, mHeight));
|
||||
if (!pdocrender)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -2074,6 +2074,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
PRBool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||
targetContent, isSelection);
|
||||
if (dragStarted) {
|
||||
sActiveESM = nsnull;
|
||||
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
}
|
||||
}
|
||||
@ -2935,7 +2936,6 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
if (par)
|
||||
activeContent = par;
|
||||
}
|
||||
SetGlobalActiveContent(this, activeContent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -2943,11 +2943,12 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
// any of our own processing of a drag. Workaround for bug 43258.
|
||||
StopTrackingDragGesture();
|
||||
}
|
||||
SetActiveManager(this, activeContent);
|
||||
}
|
||||
break;
|
||||
case NS_MOUSE_BUTTON_UP:
|
||||
{
|
||||
ClearGlobalActiveContent();
|
||||
ClearGlobalActiveContent(this);
|
||||
if (IsMouseEventReal(aEvent)) {
|
||||
if (!mCurrentTarget) {
|
||||
nsIFrame* targ;
|
||||
@ -3206,6 +3207,7 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
targetContent, &status);
|
||||
}
|
||||
}
|
||||
ClearGlobalActiveContent(this);
|
||||
break;
|
||||
}
|
||||
case NS_DRAGDROP_EXIT:
|
||||
@ -4706,22 +4708,25 @@ nsEventStateManager::DoContentCommandScrollEvent(nsContentCommandEvent* aEvent)
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::SetGlobalActiveContent(nsEventStateManager* aNewESM,
|
||||
nsIContent* aContent)
|
||||
nsEventStateManager::SetActiveManager(nsEventStateManager* aNewESM,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
if (sActiveESM && aNewESM != sActiveESM) {
|
||||
sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
sActiveESM = aNewESM;
|
||||
if (sActiveESM) {
|
||||
if (sActiveESM && aContent) {
|
||||
sActiveESM->SetContentState(aContent, NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::ClearGlobalActiveContent()
|
||||
nsEventStateManager::ClearGlobalActiveContent(nsEventStateManager* aClearer)
|
||||
{
|
||||
if (sActiveESM) {
|
||||
if (aClearer) {
|
||||
aClearer->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
if (sActiveESM && aClearer != sActiveESM) {
|
||||
sActiveESM->SetContentState(nsnull, NS_EVENT_STATE_ACTIVE);
|
||||
}
|
||||
sActiveESM = nsnull;
|
||||
|
@ -159,8 +159,10 @@ public:
|
||||
|
||||
static nsIEventStateManager* GetActiveEventStateManager() { return sActiveESM; }
|
||||
|
||||
static void SetGlobalActiveContent(nsEventStateManager* aNewESM,
|
||||
nsIContent* aContent);
|
||||
// Sets aNewESM to be the active event state manager, and
|
||||
// if aContent is non-null, marks the object as active.
|
||||
static void SetActiveManager(nsEventStateManager* aNewESM,
|
||||
nsIContent* aContent);
|
||||
protected:
|
||||
void UpdateCursor(nsPresContext* aPresContext, nsEvent* aEvent, nsIFrame* aTargetFrame, nsEventStatus* aStatus);
|
||||
/**
|
||||
@ -415,7 +417,7 @@ protected:
|
||||
|
||||
static nsEventStateManager* sActiveESM;
|
||||
|
||||
static void ClearGlobalActiveContent();
|
||||
static void ClearGlobalActiveContent(nsEventStateManager* aClearer);
|
||||
|
||||
// Functions used for click hold context menus
|
||||
PRBool mClickHoldContextMenu;
|
||||
|
31
content/html/content/crashtests/606430-1.html
Normal file
31
content/html/content/crashtests/606430-1.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var r = document.documentElement;
|
||||
var i = document.getElementById("i");
|
||||
|
||||
document.removeChild(r);
|
||||
document.appendChild(r);
|
||||
w("dump('A\\n')");
|
||||
document.removeChild(r);
|
||||
w("dump('B\\n')");
|
||||
document.appendChild(r);
|
||||
|
||||
function w(s)
|
||||
{
|
||||
var ns = document.createElement("script");
|
||||
var nt = document.createTextNode(s);
|
||||
ns.appendChild(nt);
|
||||
i.appendChild(ns);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();"><input id="i"></body>
|
||||
</html>
|
@ -20,3 +20,4 @@ load 580507-1.xhtml
|
||||
load 590387.html
|
||||
load 596785-1.html
|
||||
load 596785-2.html
|
||||
load 606430-1.html
|
||||
|
@ -64,6 +64,8 @@ public:
|
||||
|
||||
friend class nsDOMValidityState;
|
||||
|
||||
static const PRUint16 sContentSpecifiedMaxLengthMessage;
|
||||
|
||||
virtual ~nsIConstraintValidation();
|
||||
|
||||
PRBool IsValid() const { return mValidityBitField == 0; }
|
||||
|
@ -808,7 +808,8 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop, PRUint8 optional_argc)
|
||||
NS_PRESSHELL_SCROLL_BOTTOM;
|
||||
|
||||
presShell->ScrollContentIntoView(this, vpercent,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
if (NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
|
||||
nsIEventStateManager* esm =
|
||||
aVisitor.mPresContext->EventStateManager();
|
||||
nsEventStateManager::SetGlobalActiveContent(
|
||||
nsEventStateManager::SetActiveManager(
|
||||
static_cast<nsEventStateManager*>(esm), this);
|
||||
}
|
||||
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
|
||||
|
@ -3972,6 +3972,9 @@ nsHTMLInputElement::GetValidationMessage(nsAString& aValidationMessage,
|
||||
"FormValidationPatternMismatch",
|
||||
message);
|
||||
} else {
|
||||
if (title.Length() > nsIConstraintValidation::sContentSpecifiedMaxLengthMessage) {
|
||||
title.Truncate(nsIConstraintValidation::sContentSpecifiedMaxLengthMessage);
|
||||
}
|
||||
const PRUnichar* params[] = { title.get() };
|
||||
rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
|
||||
"FormValidationPatternMismatchWithTitle",
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include "nsHTMLFormElement.h"
|
||||
|
||||
|
||||
const PRUint16 nsIConstraintValidation::sContentSpecifiedMaxLengthMessage = 256;
|
||||
|
||||
nsIConstraintValidation::nsIConstraintValidation()
|
||||
: mValidityBitField(0)
|
||||
, mValidity(nsnull)
|
||||
@ -87,8 +89,14 @@ nsIConstraintValidation::GetValidationMessage(nsAString& aValidationMessage)
|
||||
|
||||
if (!authorMessage.IsEmpty()) {
|
||||
aValidationMessage.Assign(authorMessage);
|
||||
if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) {
|
||||
aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage);
|
||||
}
|
||||
} else if (GetValidityState(VALIDITY_STATE_CUSTOM_ERROR)) {
|
||||
aValidationMessage.Assign(mCustomValidity);
|
||||
if (aValidationMessage.Length() > sContentSpecifiedMaxLengthMessage) {
|
||||
aValidationMessage.Truncate(sContentSpecifiedMaxLengthMessage);
|
||||
}
|
||||
} else if (GetValidityState(VALIDITY_STATE_TOO_LONG)) {
|
||||
GetValidationMessage(aValidationMessage, VALIDITY_STATE_TOO_LONG);
|
||||
} else if (GetValidityState(VALIDITY_STATE_VALUE_MISSING)) {
|
||||
|
@ -78,6 +78,30 @@ struct SelectionState {
|
||||
PRInt32 mEnd;
|
||||
};
|
||||
|
||||
class RestoreSelectionState : public nsRunnable {
|
||||
public:
|
||||
RestoreSelectionState(nsTextControlFrame *aFrame, PRInt32 aStart, PRInt32 aEnd)
|
||||
: mFrame(aFrame),
|
||||
mWeakFrame(aFrame),
|
||||
mStart(aStart),
|
||||
mEnd(aEnd)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
if (mWeakFrame.IsAlive()) {
|
||||
mFrame->SetSelectionRange(mStart, mEnd);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsTextControlFrame* mFrame;
|
||||
nsWeakFrame mWeakFrame;
|
||||
PRInt32 mStart;
|
||||
PRInt32 mEnd;
|
||||
};
|
||||
|
||||
/*static*/
|
||||
PRBool
|
||||
nsITextControlElement::GetWrapPropertyEnum(nsIContent* aContent,
|
||||
@ -160,7 +184,7 @@ public:
|
||||
NS_IMETHOD SetSelectionFlags(PRInt16 aInEnable);
|
||||
NS_IMETHOD GetSelectionFlags(PRInt16 *aOutEnable);
|
||||
NS_IMETHOD GetSelection(PRInt16 type, nsISelection **_retval);
|
||||
NS_IMETHOD ScrollSelectionIntoView(PRInt16 aType, PRInt16 aRegion, PRBool aIsSynchronous);
|
||||
NS_IMETHOD ScrollSelectionIntoView(PRInt16 aType, PRInt16 aRegion, PRInt16 aFlags);
|
||||
NS_IMETHOD RepaintSelection(PRInt16 type);
|
||||
NS_IMETHOD RepaintSelection(nsPresContext* aPresContext, SelectionType aSelectionType);
|
||||
NS_IMETHOD SetCaretEnabled(PRBool enabled);
|
||||
@ -279,12 +303,12 @@ nsTextInputSelectionImpl::GetSelection(PRInt16 type, nsISelection **_retval)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::ScrollSelectionIntoView(PRInt16 aType, PRInt16 aRegion, PRBool aIsSynchronous)
|
||||
nsTextInputSelectionImpl::ScrollSelectionIntoView(PRInt16 aType, PRInt16 aRegion, PRInt16 aFlags)
|
||||
{
|
||||
if (!mFrameSelection)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrameSelection->ScrollSelectionIntoView(aType, aRegion, aIsSynchronous);
|
||||
return mFrameSelection->ScrollSelectionIntoView(aType, aRegion, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -461,7 +485,8 @@ nsTextInputSelectionImpl::PageMove(PRBool aForward, PRBool aExtend)
|
||||
}
|
||||
// After ScrollSelectionIntoView(), the pending notifications might be
|
||||
// flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
|
||||
return ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION, PR_TRUE);
|
||||
return ScrollSelectionIntoView(nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_FOCUS_REGION,
|
||||
nsISelectionController::SCROLL_SYNCHRONOUS);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1328,7 +1353,7 @@ nsTextEditorState::PrepareEditor(const nsAString *aValue)
|
||||
|
||||
// Restore our selection after being bound to a new frame
|
||||
if (mSelState) {
|
||||
mBoundFrame->SetSelectionRange(mSelState->mStart, mSelState->mEnd);
|
||||
nsContentUtils::AddScriptRunner(new RestoreSelectionState(mBoundFrame, mSelState->mStart, mSelState->mEnd));
|
||||
mSelState = nsnull;
|
||||
}
|
||||
|
||||
|
@ -235,6 +235,9 @@ _TEST_FILES = \
|
||||
test_bug596350.html \
|
||||
test_bug600155.html \
|
||||
test_bug556007.html \
|
||||
test_bug606817.html \
|
||||
test_bug297761.html \
|
||||
file_bug297761.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
13
content/html/content/test/file_bug297761.html
Normal file
13
content/html/content/test/file_bug297761.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<base href="http://www.mozilla.org/">
|
||||
</head>
|
||||
<body>
|
||||
<form action="">
|
||||
<input type='submit' formaction="">
|
||||
<button type='submit' formaction=""></button>
|
||||
<input id='i' type='image' formaction="">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
78
content/html/content/test/test_bug297761.html
Normal file
78
content/html/content/test/test_bug297761.html
Normal file
@ -0,0 +1,78 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=297761
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 297761</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=297761">Mozilla Bug 297761</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<iframe src="file_bug297761.html"></iframe>
|
||||
<iframe src="file_bug297761.html"></iframe>
|
||||
<iframe src="file_bug297761.html"></iframe>
|
||||
<iframe src="file_bug297761.html"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 297761 **/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var nbTests = 4;
|
||||
var curTest = 0;
|
||||
|
||||
function nextTest()
|
||||
{
|
||||
if (curTest == 3) {
|
||||
frames[curTest].document.forms[0].submit();
|
||||
} else {
|
||||
var el = null;
|
||||
if (curTest == 2) {
|
||||
el = frames[curTest].document.getElementById('i');
|
||||
} else {
|
||||
el = frames[curTest].document.forms[0].elements[curTest];
|
||||
}
|
||||
|
||||
el.focus();
|
||||
el.click();
|
||||
}
|
||||
}
|
||||
|
||||
function frameLoaded(aFrame)
|
||||
{
|
||||
var documentLocation = location.href.replace(/\.html.*/, "\.html");
|
||||
is(aFrame.contentWindow.location.href.replace(/\?x=0&y=0/, ""),
|
||||
documentLocation.replace(/test_bug/, "file_bug"),
|
||||
"form should have been submitted to the document location");
|
||||
|
||||
if (++curTest == nbTests) {
|
||||
SimpleTest.finish();
|
||||
} else {
|
||||
nextTest();
|
||||
}
|
||||
}
|
||||
|
||||
function runTest()
|
||||
{
|
||||
// Initialize event handlers.
|
||||
var frames = document.getElementsByTagName('iframe');
|
||||
for (var i=0; i<nbTests; ++i) {
|
||||
frames[i].setAttribute('onload', "frameLoaded(this);");
|
||||
}
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
addLoadEvent(runTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -22,57 +22,68 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=392567
|
||||
|
||||
/** Test for Bug 392567 **/
|
||||
|
||||
var dataUrl = "http://mochi.test:8888/tests/content/html/content/test/bug392567.jar";
|
||||
var jarUrl = "jar:" + dataUrl + "!/index.html";
|
||||
var httpUrl = location.href.replace(/\.html.*/, "_404");
|
||||
var previousDir = location.href.replace(/test\/[^\/]*$/, "");
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var form = document.forms.testForm;
|
||||
var frame = frames.testFrame;
|
||||
document.getElementById("testFrame").onload = processTestResult;
|
||||
|
||||
// List of tests to run, each test consists of form action URL and expected result URL
|
||||
var tests = [
|
||||
[jarUrl, jarUrl + "?$PARAMS", null],
|
||||
[jarUrl + "?jarTest1=jarTest2", jarUrl + "?$PARAMS", null],
|
||||
[jarUrl + "?jarTest3=jarTest4#jarTest5", jarUrl + "?$PARAMS#jarTest5", null],
|
||||
["data:text/html,<html></html>", "data:text/html,<html></html>?$PARAMS", null],
|
||||
["data:text/html,<html>How%20about%20this?</html>", "data:text/html,<html>How%20about%20this?$PARAMS", null],
|
||||
[httpUrl, httpUrl + "?$PARAMS", null],
|
||||
[httpUrl + "?httpTest1=httpTest2", httpUrl + "?$PARAMS", null ],
|
||||
[httpUrl + "?httpTest3=httpTest4#httpTest5", httpUrl + "?$PARAMS#httpTest5", null],
|
||||
["", jarUrl + "?key=value0", null],
|
||||
[" ", jarUrl + "?key=value0", document.location],
|
||||
["../", previousDir + "?$PARAMS", previousDir],
|
||||
];
|
||||
|
||||
var currentTest = -1;
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
runNextTest();
|
||||
|
||||
function runNextTest() {
|
||||
currentTest++;
|
||||
if (currentTest >= tests.length) {
|
||||
SimpleTest.finish();
|
||||
function runTests()
|
||||
{
|
||||
if (window.location.search.match(/\?key=value/)) {
|
||||
return;
|
||||
}
|
||||
|
||||
form.setAttribute("action", tests[currentTest][0]);
|
||||
is(form.action, tests[currentTest][0],
|
||||
"action IDL attribute should reflect the action content attribute");
|
||||
is(form.mozActionUri, tests[currentTest][2] ? tests[currentTest][2] : tests[currentTest][0],
|
||||
"mozActionUri IDL attribute should resolve the action URI");
|
||||
form.key.value = "value" + currentTest;
|
||||
form.submit();
|
||||
var dataUrl = "http://mochi.test:8888/tests/content/html/content/test/bug392567.jar";
|
||||
var jarUrl = "jar:" + dataUrl + "!/index.html";
|
||||
var httpUrl = location.href.replace(/\.html.*/, "_404");
|
||||
var previousDir = location.href.replace(/test\/[^\/]*$/, "");
|
||||
var documentURL = location.href.replace(/\.html.*/, "\.html");
|
||||
|
||||
var form = document.forms.testForm;
|
||||
var frame = frames.testFrame;
|
||||
document.getElementById("testFrame").onload = processTestResult;
|
||||
|
||||
// List of tests to run, each test consists of form action URL and expected result URL
|
||||
var tests = [
|
||||
[jarUrl, jarUrl + "?$PARAMS", null],
|
||||
[jarUrl + "?jarTest1=jarTest2", jarUrl + "?$PARAMS", null],
|
||||
[jarUrl + "?jarTest3=jarTest4#jarTest5", jarUrl + "?$PARAMS#jarTest5", null],
|
||||
["data:text/html,<html></html>", "data:text/html,<html></html>?$PARAMS", null],
|
||||
["data:text/html,<html>How%20about%20this?</html>", "data:text/html,<html>How%20about%20this?$PARAMS", null],
|
||||
[httpUrl, httpUrl + "?$PARAMS", null],
|
||||
[httpUrl + "?httpTest1=httpTest2", httpUrl + "?$PARAMS", null ],
|
||||
[httpUrl + "?httpTest3=httpTest4#httpTest5", httpUrl + "?$PARAMS#httpTest5", null],
|
||||
["", documentURL + "?$PARAMS", null],
|
||||
[" ", documentURL + "?$PARAMS", document.location],
|
||||
["../", previousDir + "?$PARAMS", previousDir],
|
||||
];
|
||||
|
||||
var currentTest = -1;
|
||||
|
||||
runNextTest();
|
||||
|
||||
function runNextTest() {
|
||||
currentTest++;
|
||||
if (currentTest >= tests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
form.setAttribute("action", tests[currentTest][0]);
|
||||
is(form.action, tests[currentTest][0],
|
||||
"action IDL attribute should reflect the action content attribute");
|
||||
is(form.mozActionUri, tests[currentTest][2] ? tests[currentTest][2] : tests[currentTest][0],
|
||||
"mozActionUri IDL attribute should resolve the action URI");
|
||||
form.key.value = "value" + currentTest;
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function processTestResult() {
|
||||
var expected = tests[currentTest][1].replace(/\$PARAMS/, "key=value" + currentTest);
|
||||
is(frame.location.href, expected, "Submitting to " + tests[currentTest][0]);
|
||||
|
||||
setTimeout(runNextTest, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function processTestResult() {
|
||||
var expected = tests[currentTest][1].replace(/\$PARAMS/, "key=value" + currentTest);
|
||||
is(frame.location.href, expected, "Submitting to " + tests[currentTest][0]);
|
||||
|
||||
setTimeout(runNextTest, 0);
|
||||
}
|
||||
addLoadEvent(runTests);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
65
content/html/content/test/test_bug606817.html
Normal file
65
content/html/content/test/test_bug606817.html
Normal file
@ -0,0 +1,65 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=606817
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 606817</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=606817">Mozilla Bug 606817</a>
|
||||
<p id="display"></p>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 606817 **/
|
||||
|
||||
var messageMaxLength = 256;
|
||||
|
||||
function checkMessage(aInput, aMsg, aWithTerminalPeriod)
|
||||
{
|
||||
ok(aInput.validationMessage != aMsg,
|
||||
"Original content-defined message should have been truncate");
|
||||
is(aInput.validationMessage.length - aInput.validationMessage.indexOf("_42_"),
|
||||
aWithTerminalPeriod ? messageMaxLength+1 : messageMaxLength,
|
||||
"validation message should be 256 characters length");
|
||||
}
|
||||
|
||||
var input = document.createElement("input");
|
||||
|
||||
var msg = "";
|
||||
for (var i=0; i<75; ++i) {
|
||||
msg += "_42_";
|
||||
}
|
||||
// msg is now 300 chars long
|
||||
|
||||
// Testing with setCustomValidity().
|
||||
input.setCustomValidity(msg);
|
||||
checkMessage(input, msg, false);
|
||||
|
||||
// The input is still invalid but x-moz-errormessage will be used as the message.
|
||||
input.setAttribute("x-moz-errormessage", msg);
|
||||
checkMessage(input, msg, false);
|
||||
|
||||
// Cleaning.
|
||||
input.setCustomValidity("");
|
||||
input.removeAttribute("x-moz-errormessage");
|
||||
|
||||
// Testing with pattern and titl.
|
||||
input.pattern = "[0-9]*";
|
||||
input.value = "foo";
|
||||
input.title = msg;
|
||||
checkMessage(input, msg, true);
|
||||
|
||||
// Cleaning.
|
||||
input.removeAttribute("pattern");
|
||||
input.removeAttribute("title");
|
||||
input.value = "";
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -65,9 +65,10 @@ function startTest(test, token) {
|
||||
if (v.parentNode) {
|
||||
v.parentNode.removeChild(v);
|
||||
}
|
||||
dump("SEEK-TEST: Finished " + name + "\n");
|
||||
manager.finished(v.token);
|
||||
}}(v, manager);
|
||||
dump("Seek test: " + test.number + "\n");
|
||||
dump("SEEK-TEST: Started " + name + "\n");
|
||||
window['test_seek' + test.number](v, test.duration/2, localIs, localOk, localFinish);
|
||||
}
|
||||
|
||||
|
@ -404,6 +404,8 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
nsCOMArray<nsIContent> updaters;
|
||||
|
||||
for (Updater* updater = mUpdaters; updater != nsnull; updater = updater->mNext) {
|
||||
// Skip any nodes that don't match our 'events' or 'targets'
|
||||
// filters.
|
||||
@ -418,6 +420,12 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
||||
if (! content)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
updaters.AppendObject(content);
|
||||
}
|
||||
|
||||
for (PRUint32 u = 0; u < updaters.Count(); u++) {
|
||||
nsIContent* content = updaters[u];
|
||||
|
||||
nsCOMPtr<nsIDocument> document = content->GetDocument();
|
||||
|
||||
NS_ASSERTION(document != nsnull, "element has no document");
|
||||
@ -430,7 +438,7 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
||||
CopyUTF16toUTF8(aEventName, aeventnameC);
|
||||
PR_LOG(gLog, PR_LOG_NOTICE,
|
||||
("xulcmd[%p] update %p event=%s",
|
||||
this, updater->mElement.get(),
|
||||
this, content,
|
||||
aeventnameC.get()));
|
||||
}
|
||||
#endif
|
||||
|
@ -145,6 +145,7 @@ NS_NewXULPrototypeCache(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
nsXULPrototypeCache *p = result;
|
||||
obsSvc->AddObserver(p, "chrome-flush-skin-caches", PR_FALSE);
|
||||
obsSvc->AddObserver(p, "chrome-flush-caches", PR_FALSE);
|
||||
obsSvc->AddObserver(p, "startupcache-invalidate", PR_FALSE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -410,10 +411,6 @@ nsXULPrototypeCache::AbortFastLoads()
|
||||
NS_BREAK();
|
||||
#endif
|
||||
|
||||
// Save a strong ref to the FastLoad file, so we can remove it after we
|
||||
// close open streams to it.
|
||||
nsCOMPtr<nsIFile> file = gFastLoadFile;
|
||||
|
||||
// Flush the XUL cache for good measure, in case we cached a bogus/downrev
|
||||
// script, somehow.
|
||||
Flush();
|
||||
@ -421,29 +418,42 @@ nsXULPrototypeCache::AbortFastLoads()
|
||||
// Clear the FastLoad set
|
||||
mFastLoadURITable.Clear();
|
||||
|
||||
if (! gFastLoadService)
|
||||
return;
|
||||
nsCOMPtr<nsIFastLoadService> fastLoadService = gFastLoadService;
|
||||
nsCOMPtr<nsIFile> file = gFastLoadFile;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (! fastLoadService) {
|
||||
fastLoadService = do_GetFastLoadService();
|
||||
if (! fastLoadService)
|
||||
return;
|
||||
|
||||
rv = fastLoadService->NewFastLoadFile(XUL_FASTLOAD_FILE_BASENAME,
|
||||
getter_AddRefs(file));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the current input (if FastLoad file existed) or output (if we're
|
||||
// creating the FastLoad file during this app startup) stream.
|
||||
nsCOMPtr<nsIObjectInputStream> objectInput;
|
||||
nsCOMPtr<nsIObjectOutputStream> objectOutput;
|
||||
gFastLoadService->GetInputStream(getter_AddRefs(objectInput));
|
||||
gFastLoadService->GetOutputStream(getter_AddRefs(objectOutput));
|
||||
fastLoadService->GetInputStream(getter_AddRefs(objectInput));
|
||||
fastLoadService->GetOutputStream(getter_AddRefs(objectOutput));
|
||||
|
||||
if (objectOutput) {
|
||||
gFastLoadService->SetOutputStream(nsnull);
|
||||
fastLoadService->SetOutputStream(nsnull);
|
||||
|
||||
if (NS_SUCCEEDED(objectOutput->Close()) && gChecksumXULFastLoadFile)
|
||||
gFastLoadService->CacheChecksum(gFastLoadFile,
|
||||
objectOutput);
|
||||
fastLoadService->CacheChecksum(file,
|
||||
objectOutput);
|
||||
}
|
||||
|
||||
if (objectInput) {
|
||||
// If this is the last of one or more XUL master documents loaded
|
||||
// together at app startup, close the FastLoad service's singleton
|
||||
// input stream now.
|
||||
gFastLoadService->SetInputStream(nsnull);
|
||||
fastLoadService->SetInputStream(nsnull);
|
||||
objectInput->Close();
|
||||
}
|
||||
|
||||
@ -462,13 +472,15 @@ nsXULPrototypeCache::AbortFastLoads()
|
||||
}
|
||||
file->MoveToNative(nsnull, NS_LITERAL_CSTRING("Aborted.mfasl"));
|
||||
#else
|
||||
file->Remove(PR_FALSE);
|
||||
rv = file->Remove(PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Failed to remove fastload file, fastload data may be outdated");
|
||||
#endif
|
||||
}
|
||||
|
||||
// If the list is empty now, the FastLoad process is done.
|
||||
NS_RELEASE(gFastLoadService);
|
||||
NS_RELEASE(gFastLoadFile);
|
||||
NS_IF_RELEASE(gFastLoadService);
|
||||
NS_IF_RELEASE(gFastLoadFile);
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,6 +57,8 @@ _TEST_FILES = \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
test_bug583948.xul \
|
||||
window_bug583948.xul \
|
||||
test_bug497875.xul \
|
||||
bug497875-iframe.xul \
|
||||
$(NULL)
|
||||
|
41
content/xul/document/test/test_bug583948.xul
Normal file
41
content/xul/document/test/test_bug583948.xul
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<div id="content" style="display: none"/>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var attempts = 0;
|
||||
|
||||
function update() {
|
||||
setTimeout(function() {
|
||||
if (otherWindow.location)
|
||||
otherWindow.location.reload()
|
||||
}, 1);
|
||||
otherWindow.document.commandDispatcher.updateCommands('');
|
||||
// without the crash fix, this usually crashes after 2 to 4 reloads
|
||||
if (++attempts == 6) {
|
||||
ok(true, "didn't crash after 6 attempts");
|
||||
otherWindow.close();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
else {
|
||||
setTimeout(update, 100);
|
||||
}
|
||||
}
|
||||
|
||||
var otherWindow = window.open("window_bug583948.xul", "_new", "chrome");
|
||||
setTimeout(update, 100);
|
||||
</script>
|
||||
|
||||
</window>
|
8
content/xul/document/test/window_bug583948.xul
Normal file
8
content/xul/document/test/window_bug583948.xul
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<command oncommandupdate="document.removeChild(document.documentElement)" commandupdater="true"/>
|
||||
<box command="c"/>
|
||||
<iframe/>
|
||||
|
||||
</window>
|
@ -1139,13 +1139,8 @@ nsXULTemplateBuilder::AttributeChanged(nsIDocument* aDocument,
|
||||
// Check for a change to the 'datasources' attribute. If so, setup
|
||||
// mDB by parsing the new value and rebuild.
|
||||
else if (aAttribute == nsGkAtoms::datasources) {
|
||||
Uninit(PR_FALSE); // Reset results
|
||||
|
||||
PRBool shouldDelay;
|
||||
LoadDataSources(aDocument, &shouldDelay);
|
||||
if (!shouldDelay)
|
||||
nsContentUtils::AddScriptRunner(
|
||||
NS_NewRunnableMethod(this, &nsXULTemplateBuilder::RunnableRebuild));
|
||||
nsContentUtils::AddScriptRunner(
|
||||
NS_NewRunnableMethod(this, &nsXULTemplateBuilder::RunnableLoadAndRebuild));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1163,8 +1158,9 @@ nsXULTemplateBuilder::ContentRemoved(nsIDocument* aDocument,
|
||||
if (mQueryProcessor)
|
||||
mQueryProcessor->Done();
|
||||
|
||||
// use false since content is going away anyway
|
||||
Uninit(PR_FALSE);
|
||||
// Pass false to Uninit since content is going away anyway
|
||||
nsContentUtils::AddScriptRunner(
|
||||
NS_NewRunnableMethod(this, &nsXULTemplateBuilder::UninitFalse));
|
||||
|
||||
aDocument->RemoveObserver(this);
|
||||
|
||||
@ -1201,7 +1197,8 @@ nsXULTemplateBuilder::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
mCompDB = nsnull;
|
||||
mRoot = nsnull;
|
||||
|
||||
Uninit(PR_TRUE);
|
||||
nsContentUtils::AddScriptRunner(
|
||||
NS_NewRunnableMethod(this, &nsXULTemplateBuilder::UninitTrue));
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,6 +152,20 @@ public:
|
||||
RebuildAll() = 0; // must be implemented by subclasses
|
||||
|
||||
void RunnableRebuild() { Rebuild(); }
|
||||
void RunnableLoadAndRebuild() {
|
||||
Uninit(PR_FALSE); // Reset results
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = mRoot ? mRoot->GetDocument() : nsnull;
|
||||
if (doc) {
|
||||
PRBool shouldDelay;
|
||||
LoadDataSources(doc, &shouldDelay);
|
||||
if (!shouldDelay) {
|
||||
Rebuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
void UninitFalse() { Uninit(PR_FALSE); }
|
||||
void UninitTrue() { Uninit(PR_TRUE); }
|
||||
|
||||
/**
|
||||
* Find the <template> tag that applies for this builder
|
||||
|
@ -27,8 +27,7 @@ function checkConsole(expectedError)
|
||||
{
|
||||
var out = {};
|
||||
consoleService.getMessageArray(out, {});
|
||||
var messages = out.value || [];
|
||||
is(messages[0].message, expectedError, "logged message " + expectedError);
|
||||
is(out.value[0].message, expectedError, "logged message " + expectedError);
|
||||
}
|
||||
|
||||
// each test consists of a pre function executed before the template build, an
|
||||
|
@ -159,7 +159,7 @@
|
||||
#include "nsIController.h"
|
||||
#include "nsPICommandUpdater.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIWebBrowserChrome2.h"
|
||||
#include "nsIWebBrowserChrome3.h"
|
||||
#include "nsITabChild.h"
|
||||
#include "nsIStrictTransportSecurityService.h"
|
||||
|
||||
@ -711,6 +711,7 @@ nsDocShell::nsDocShell():
|
||||
mAllowKeywordFixup(PR_FALSE),
|
||||
mIsOffScreenBrowser(PR_FALSE),
|
||||
mIsActive(PR_TRUE),
|
||||
mIsAppTab(PR_FALSE),
|
||||
mFiredUnloadEvent(PR_FALSE),
|
||||
mEODForCurrentDocument(PR_FALSE),
|
||||
mURIResultedInDocument(PR_FALSE),
|
||||
@ -4802,6 +4803,20 @@ nsDocShell::GetIsActive(PRBool *aIsActive)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetIsAppTab(PRBool aIsAppTab)
|
||||
{
|
||||
mIsAppTab = aIsAppTab;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsAppTab(PRBool *aIsAppTab)
|
||||
{
|
||||
*aIsAppTab = mIsAppTab;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetVisibility(PRBool aVisibility)
|
||||
{
|
||||
@ -11311,8 +11326,22 @@ nsDocShell::OnLinkClick(nsIContent* aContent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
nsAutoString target;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserChrome3> browserChrome3 = do_GetInterface(mTreeOwner);
|
||||
if (browserChrome3) {
|
||||
nsCOMPtr<nsIDOMNode> linkNode = do_QueryInterface(aContent);
|
||||
nsAutoString oldTarget(aTargetSpec);
|
||||
rv = browserChrome3->OnBeforeLinkTraversal(oldTarget, aURI,
|
||||
linkNode, mIsAppTab, target);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
target = aTargetSpec;
|
||||
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new OnLinkClickEvent(this, aContent, aURI, aTargetSpec,
|
||||
new OnLinkClickEvent(this, aContent, aURI, target.get(),
|
||||
aPostDataStream, aHeadersDataStream);
|
||||
return NS_DispatchToCurrentThread(ev);
|
||||
}
|
||||
|
@ -790,6 +790,7 @@ protected:
|
||||
PRPackedBool mAllowKeywordFixup;
|
||||
PRPackedBool mIsOffScreenBrowser;
|
||||
PRPackedBool mIsActive;
|
||||
PRPackedBool mIsAppTab;
|
||||
|
||||
// This boolean is set to true right before we fire pagehide and generally
|
||||
// unset when we embed a new content viewer. While it's true no navigation
|
||||
|
@ -71,7 +71,7 @@ interface nsIPrincipal;
|
||||
interface nsIWebBrowserPrint;
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(74470127-87eb-4f79-8293-1616fe9cb689)]
|
||||
[scriptable, uuid(98cdbcc4-2d81-4191-a63f-b6c52085edbc)]
|
||||
interface nsIDocShell : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -529,11 +529,17 @@ interface nsIDocShell : nsISupports
|
||||
*/
|
||||
attribute boolean isActive;
|
||||
|
||||
|
||||
/**
|
||||
* The ID of the docshell in the session history.
|
||||
*/
|
||||
readonly attribute unsigned long long historyID;
|
||||
|
||||
/**
|
||||
* Sets whether a docshell is an app tab. An app tab docshell may behave
|
||||
* differently than a non-app tab docshell in some cases, such as when
|
||||
* handling link clicks. Docshells are not app tabs unless told otherwise.
|
||||
*/
|
||||
attribute boolean isAppTab;
|
||||
};
|
||||
|
||||
[uuid(5f7a2184-31b6-4d67-9c75-0c17477766e2)]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user