зеркало из https://github.com/mozilla/gecko-dev.git
checkin for sballard@netreach.net.
bug 103097: make the UI for the <link> element faster r=fabian, sr=blake
This commit is contained in:
Родитель
c92c1f3024
Коммит
657a7116ce
|
@ -51,22 +51,6 @@ function LinkToolbarHandler()
|
|||
this.hasItems = false;
|
||||
}
|
||||
|
||||
LinkToolbarHandler.prototype.handleLinks =
|
||||
function(nodeList)
|
||||
{
|
||||
if (!nodeList) return;
|
||||
|
||||
var len = nodeList.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
// optimization: weed out useless links here to avoid
|
||||
// the function call. More in depth checks are done
|
||||
// in this.handle
|
||||
var node = nodeList.item(i);
|
||||
if (node && (node.rel || node.rev) && node.href)
|
||||
this.handle(node);
|
||||
}
|
||||
}
|
||||
|
||||
LinkToolbarHandler.prototype.handle =
|
||||
function(element)
|
||||
{
|
||||
|
@ -76,7 +60,10 @@ function(element)
|
|||
|
||||
if (linkElement.isIgnored()) return;
|
||||
|
||||
this.hasItems = true;
|
||||
if (!this.hasItems) {
|
||||
this.hasItems = true;
|
||||
linkToolbarUI.activate();
|
||||
}
|
||||
|
||||
var relAttributes = linkElement.rel.split(" ");
|
||||
for (var i = 0; i < relAttributes.length; i++) {
|
||||
|
@ -130,7 +117,7 @@ function(relAttribute)
|
|||
|
||||
LinkToolbarHandler.prototype.getItemForLinkType =
|
||||
function(linkType) {
|
||||
if (!this.items[linkType])
|
||||
if (!(linkType in this.items && this.items[linkType]))
|
||||
this.items[linkType] = LinkToolbarHandler.createItemForLinkType(linkType);
|
||||
|
||||
return this.items[linkType];
|
||||
|
@ -161,8 +148,14 @@ function(linkType)
|
|||
LinkToolbarHandler.prototype.clearAllItems =
|
||||
function()
|
||||
{
|
||||
// Hide the 'miscellaneous' separator
|
||||
document.getElementById("misc-separator").setAttribute("collapsed", "true");
|
||||
|
||||
// Disable the individual items
|
||||
for (var linkType in this.items)
|
||||
this.items[linkType].clear();
|
||||
|
||||
// Store the fact that the toolbar is empty
|
||||
this.hasItems = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* Contributor(s):
|
||||
* Christopher Hoess <choess@force.stwing.upenn.edu>
|
||||
* Tim Taylor <tim@tool-man.org>
|
||||
* Stuart Ballard <sballard@netreach.net>
|
||||
*
|
||||
* 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
|
||||
|
@ -258,21 +259,12 @@ function LinkToolbarTransientMenu (linkType) {
|
|||
if(!this.__proto__.displayLink.apply(this, [linkElement])) return false;
|
||||
|
||||
this.getXULElement().removeAttribute("collapsed");
|
||||
showMiscellaneousSeparator();
|
||||
|
||||
// Show the 'miscellaneous' separator
|
||||
document.getElementById("misc-separator").removeAttribute("collapsed");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
showMiscellaneousSeparator =
|
||||
function()
|
||||
{
|
||||
document.getElementById("misc-separator").removeAttribute("collapsed");
|
||||
}
|
||||
|
||||
hideMiscellaneousSeparator =
|
||||
function()
|
||||
{
|
||||
document.getElementById("misc-separator").setAttribute("collapsed", "true");
|
||||
}
|
||||
LinkToolbarTransientMenu.prototype = new LinkToolbarMenu;
|
||||
|
||||
|
|
|
@ -38,29 +38,22 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* called on every page load
|
||||
*
|
||||
* FIXME: refresh isn't called until the entire document has finished loading
|
||||
* XXX: optimization: don't refresh when page reloaded if the page hasn't
|
||||
* been modified
|
||||
* XXX: optimization: don't refresh when toolbar is compacted
|
||||
*/
|
||||
|
||||
LinkToolbarUI = function()
|
||||
var LinkToolbarUI = function()
|
||||
{
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.refresh =
|
||||
LinkToolbarUI.prototype.linkAdded =
|
||||
function(event)
|
||||
{
|
||||
if (event.originalTarget != getBrowser().contentDocument)
|
||||
var element = event.originalTarget;
|
||||
|
||||
if (element.ownerDocument != getBrowser().contentDocument ||
|
||||
!linkToolbarUI.isLinkToolbarEnabled() ||
|
||||
!element instanceof Components.interfaces.nsIDOMHTMLLinkElement ||
|
||||
!element.href || (!element.rel && !element.rev))
|
||||
return;
|
||||
|
||||
if (!linkToolbarUI.isLinkToolbarEnabled())
|
||||
return;
|
||||
|
||||
linkToolbarUI.doRefresh();
|
||||
linkToolbarHandler.handle(element);
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.isLinkToolbarEnabled =
|
||||
|
@ -72,87 +65,84 @@ function()
|
|||
return true;
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.doRefresh =
|
||||
LinkToolbarUI.prototype.clear =
|
||||
function(event)
|
||||
{
|
||||
if (event.originalTarget != getBrowser().contentDocument ||
|
||||
!linkToolbarUI.isLinkToolbarEnabled() ||
|
||||
!linkToolbarHandler.hasItems)
|
||||
return;
|
||||
|
||||
linkToolbarHandler.clearAllItems();
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.fullSlowRefresh =
|
||||
function()
|
||||
{
|
||||
// Not doing <meta http-equiv> elements yet.
|
||||
// If you enable checking for A links, the browser becomes
|
||||
// unresponsive during this call...for as long as 2 or more
|
||||
// seconds on heavily linked documents.
|
||||
|
||||
var currentNode = window._content.document.documentElement;
|
||||
if(!(currentNode instanceof Components.interfaces.nsIDOMHTMLHtmlElement)) return;
|
||||
var currentNode = getBrowser().contentDocument.documentElement;
|
||||
if (!(currentNode instanceof Components.interfaces.nsIDOMHTMLHtmlElement))
|
||||
return;
|
||||
currentNode = currentNode.firstChild;
|
||||
|
||||
while(currentNode) {
|
||||
if(currentNode instanceof Components.interfaces.nsIDOMHTMLHeadElement) {
|
||||
while(currentNode)
|
||||
{
|
||||
if (currentNode instanceof Components.interfaces.nsIDOMHTMLHeadElement) {
|
||||
currentNode = currentNode.firstChild;
|
||||
|
||||
while(currentNode) {
|
||||
if ((currentNode instanceof Components.interfaces.nsIDOMHTMLLinkElement) &&
|
||||
(currentNode.rel || currentNode.rev) &&
|
||||
currentNode.href) {
|
||||
linkToolbarHandler.handle(currentNode);
|
||||
}
|
||||
|
||||
while(currentNode)
|
||||
{
|
||||
if (currentNode instanceof Components.interfaces.nsIDOMHTMLLinkElement)
|
||||
linkToolbarUI.linkAdded({originalTarget: currentNode});
|
||||
currentNode = currentNode.nextSibling;
|
||||
}
|
||||
} else if (currentNode instanceof Components.interfaces.nsIDOMElement) {
|
||||
}
|
||||
else if (currentNode instanceof Components.interfaces.nsIDOMElement)
|
||||
{
|
||||
// head is supposed to be the first element inside html.
|
||||
// Got something else instead. returning
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Got a comment node or something like that. Moving on.
|
||||
currentNode = currentNode.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("linktoolbar").
|
||||
setAttribute("hasitems", linkToolbarHandler.hasItems);
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.getLinkElements =
|
||||
LinkToolbarUI.prototype.toolbarActive = false;
|
||||
|
||||
LinkToolbarUI.prototype.activate =
|
||||
function()
|
||||
{
|
||||
return getHeadElement().getElementsByTagName("link");
|
||||
if (!linkToolbarUI.toolbarActive) {
|
||||
linkToolbarUI.toolbarActive = true;
|
||||
document.getElementById("linktoolbar").setAttribute("hasitems", "true");
|
||||
var contentArea = document.getElementById("appcontent");
|
||||
contentArea.addEventListener("unload", linkToolbarUI.clear, true);
|
||||
contentArea.addEventListener("load", linkToolbarUI.deactivate, true);
|
||||
contentArea.addEventListener("DOMHeadLoaded", linkToolbarUI.deactivate,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.getHeadElement =
|
||||
LinkToolbarUI.prototype.deactivate =
|
||||
function()
|
||||
{
|
||||
return window._content.document.getElementsByTagName("head").item(0);
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.getAnchorElements =
|
||||
function()
|
||||
{
|
||||
// XXX: document.links includes AREA links, which technically
|
||||
// shouldn't be checked for REL attributes
|
||||
// FIXME: doesn't work on XHTML served as application/xhtml+xml
|
||||
return window._content.document.links;
|
||||
}
|
||||
|
||||
/** called on every page unload */
|
||||
LinkToolbarUI.prototype.clear =
|
||||
function(event)
|
||||
{
|
||||
if (event.originalTarget != getBrowser().contentDocument)
|
||||
return;
|
||||
|
||||
if (!linkToolbarUI.isLinkToolbarEnabled())
|
||||
return;
|
||||
|
||||
if (!linkToolbarHandler.hasItems)
|
||||
return;
|
||||
|
||||
linkToolbarUI.doClear();
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.doClear =
|
||||
function()
|
||||
{
|
||||
hideMiscellaneousSeparator();
|
||||
linkToolbarHandler.clearAllItems();
|
||||
// This function can never be called unless the toolbar is active, because
|
||||
// it's a handler that's only activated in that situation, so there's no need
|
||||
// to check toolbarActive. On the other hand, by the time this method is
|
||||
// called the toolbar might have been populated again already, in which case
|
||||
// we don't want to deactivate.
|
||||
if (!linkToolbarHandler.hasItems) {
|
||||
linkToolbarUI.toolbarActive = false;
|
||||
document.getElementById("linktoolbar").setAttribute("hasitems", "false");
|
||||
var contentArea = document.getElementById("appcontent");
|
||||
contentArea.removeEventListener("unload", linkToolbarUI.clear, true);
|
||||
contentArea.removeEventListener("load", linkToolbarUI.deactivate, true);
|
||||
contentArea.removeEventListener("DOMHeadLoaded", linkToolbarUI.deactivate,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
/* called whenever something on the toolbar is clicked */
|
||||
|
@ -189,9 +179,9 @@ function(checkedItem)
|
|||
this.goToggleTristateToolbar("linktoolbar", checkedItem);
|
||||
this.initHandlers();
|
||||
if (this.isLinkToolbarEnabled())
|
||||
this.doRefresh();
|
||||
this.fullSlowRefresh();
|
||||
else
|
||||
this.doClear();
|
||||
linkToolbarHandler.clearAllItems();
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.initLinkbarVisibilityMenu =
|
||||
|
@ -204,6 +194,7 @@ function()
|
|||
checkedItem.setAttribute("checked", true);
|
||||
checkedItem.checked = true;
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.goToggleTristateToolbar =
|
||||
function(id, checkedItem)
|
||||
{
|
||||
|
@ -214,23 +205,26 @@ function(id, checkedItem)
|
|||
document.persist(id, "hidden");
|
||||
}
|
||||
}
|
||||
|
||||
LinkToolbarUI.prototype.addHandlerActive = false;
|
||||
|
||||
LinkToolbarUI.prototype.initHandlers =
|
||||
function()
|
||||
{
|
||||
var contentArea = document.getElementById("appcontent");
|
||||
if (linkToolbarUI.isLinkToolbarEnabled())
|
||||
{
|
||||
if (!linkToolbarUI.handlersActive) {
|
||||
contentArea.addEventListener("load", linkToolbarUI.refresh, true);
|
||||
contentArea.addEventListener("unload", linkToolbarUI.clear, true);
|
||||
linkToolbarUI.handlersActive = true;
|
||||
if (!linkToolbarUI.addHandlerActive) {
|
||||
contentArea.addEventListener("DOMLinkAdded", linkToolbarUI.linkAdded,
|
||||
true);
|
||||
linkToolbarUI.addHandlerActive = true;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (linkToolbarUI.handlersActive) {
|
||||
contentArea.removeEventListener("load", linkToolbarUI.refresh, true);
|
||||
contentArea.removeEventListener("unload", linkToolbarUI.clear, true);
|
||||
linkToolbarUI.handlersActive = false;
|
||||
if (linkToolbarUI.addHandlerActive) {
|
||||
contentArea.removeEventListener("DOMLinkAdded", linkToolbarUI.linkAdded,
|
||||
true);
|
||||
linkToolbarUI.addHandlerActive = false;
|
||||
}
|
||||
}
|
||||
if (!linkToolbarUI.initialized)
|
||||
|
|
Загрузка…
Ссылка в новой задаче