1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/places/content/menu.xml Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,616 @@ 1.4 +<?xml version="1.0"?> 1.5 + 1.6 +# This Source Code Form is subject to the terms of the Mozilla Public 1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + 1.10 +<bindings id="placesMenuBindings" 1.11 + xmlns="http://www.mozilla.org/xbl" 1.12 + xmlns:xbl="http://www.mozilla.org/xbl" 1.13 + xmlns:html="http://www.w3.org/1999/xhtml" 1.14 + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.15 + 1.16 + <binding id="places-popup-base" 1.17 + extends="chrome://global/content/bindings/popup.xml#popup"> 1.18 + <content> 1.19 + <xul:hbox flex="1"> 1.20 + <xul:vbox class="menupopup-drop-indicator-bar" hidden="true"> 1.21 + <xul:image class="menupopup-drop-indicator" mousethrough="always"/> 1.22 + </xul:vbox> 1.23 + <xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical" 1.24 + smoothscroll="false"> 1.25 + <children/> 1.26 + </xul:arrowscrollbox> 1.27 + </xul:hbox> 1.28 + </content> 1.29 + 1.30 + <implementation> 1.31 + 1.32 + <field name="_indicatorBar"> 1.33 + document.getAnonymousElementByAttribute(this, "class", 1.34 + "menupopup-drop-indicator-bar"); 1.35 + </field> 1.36 + 1.37 + <field name="_scrollBox"> 1.38 + document.getAnonymousElementByAttribute(this, "class", 1.39 + "popup-internal-box"); 1.40 + </field> 1.41 + 1.42 + <!-- This is the view that manage the popup --> 1.43 + <field name="_rootView">PlacesUIUtils.getViewForNode(this);</field> 1.44 + 1.45 + <!-- Check if we should hide the drop indicator for the target --> 1.46 + <method name="_hideDropIndicator"> 1.47 + <parameter name="aEvent"/> 1.48 + <body><![CDATA[ 1.49 + let target = aEvent.target; 1.50 + 1.51 + // Don't draw the drop indicator outside of markers. 1.52 + // The markers are hidden, since otherwise sometimes popups acquire 1.53 + // scrollboxes on OS X, so we can't use them directly. 1.54 + let firstChildTop = this._startMarker.nextSibling.boxObject.y; 1.55 + let lastChildBottom = this._endMarker.previousSibling.boxObject.y + 1.56 + this._endMarker.previousSibling.boxObject.height; 1.57 + let betweenMarkers = target.boxObject.y >= firstChildTop || 1.58 + target.boxObject.y <= lastChildBottom; 1.59 + 1.60 + // Hide the dropmarker if current node is not a Places node. 1.61 + return !(target && target._placesNode && betweenMarkers); 1.62 + ]]></body> 1.63 + </method> 1.64 + 1.65 + <!-- This function returns information about where to drop when 1.66 + dragging over this popup insertion point --> 1.67 + <method name="_getDropPoint"> 1.68 + <parameter name="aEvent"/> 1.69 + <body><![CDATA[ 1.70 + // Can't drop if the menu isn't a folder 1.71 + let resultNode = this._placesNode; 1.72 + 1.73 + if (!PlacesUtils.nodeIsFolder(resultNode) || 1.74 + PlacesControllerDragHelper.disallowInsertion(resultNode)) { 1.75 + return null; 1.76 + } 1.77 + 1.78 + var dropPoint = { ip: null, folderElt: null }; 1.79 + 1.80 + // The element we are dragging over 1.81 + let elt = aEvent.target; 1.82 + if (elt.localName == "menupopup") 1.83 + elt = elt.parentNode; 1.84 + 1.85 + // Calculate positions taking care of arrowscrollbox 1.86 + let scrollbox = this._scrollBox; 1.87 + let eventY = aEvent.layerY + (scrollbox.boxObject.y - this.boxObject.y); 1.88 + let scrollboxOffset = scrollbox.scrollBoxObject.y - 1.89 + (scrollbox.boxObject.y - this.boxObject.y); 1.90 + let eltY = elt.boxObject.y - scrollboxOffset; 1.91 + let eltHeight = elt.boxObject.height; 1.92 + 1.93 + if (!elt._placesNode) { 1.94 + // If we are dragging over a non places node drop at the end. 1.95 + dropPoint.ip = new InsertionPoint( 1.96 + PlacesUtils.getConcreteItemId(resultNode), 1.97 + -1, 1.98 + Ci.nsITreeView.DROP_ON); 1.99 + // We can set folderElt if we are dropping over a static menu that 1.100 + // has an internal placespopup. 1.101 + let isMenu = elt.localName == "menu" || 1.102 + (elt.localName == "toolbarbutton" && 1.103 + elt.getAttribute("type") == "menu"); 1.104 + if (isMenu && elt.lastChild && 1.105 + elt.lastChild.hasAttribute("placespopup")) 1.106 + dropPoint.folderElt = elt; 1.107 + return dropPoint; 1.108 + } 1.109 + else if ((PlacesUtils.nodeIsFolder(elt._placesNode) || 1.110 + PlacesUtils.nodeIsTagQuery(elt._placesNode)) && 1.111 + !PlacesUtils.nodeIsReadOnly(elt._placesNode)) { 1.112 + // This is a folder or a tag container. 1.113 + if (eventY - eltY < eltHeight * 0.20) { 1.114 + // If mouse is in the top part of the element, drop above folder. 1.115 + dropPoint.ip = new InsertionPoint( 1.116 + PlacesUtils.getConcreteItemId(resultNode), 1.117 + -1, 1.118 + Ci.nsITreeView.DROP_BEFORE, 1.119 + PlacesUtils.nodeIsTagQuery(elt._placesNode), 1.120 + elt._placesNode.itemId); 1.121 + return dropPoint; 1.122 + } 1.123 + else if (eventY - eltY < eltHeight * 0.80) { 1.124 + // If mouse is in the middle of the element, drop inside folder. 1.125 + dropPoint.ip = new InsertionPoint( 1.126 + PlacesUtils.getConcreteItemId(elt._placesNode), 1.127 + -1, 1.128 + Ci.nsITreeView.DROP_ON, 1.129 + PlacesUtils.nodeIsTagQuery(elt._placesNode)); 1.130 + dropPoint.folderElt = elt; 1.131 + return dropPoint; 1.132 + } 1.133 + } 1.134 + else if (eventY - eltY <= eltHeight / 2) { 1.135 + // This is a non-folder node or a readonly folder. 1.136 + // If the mouse is above the middle, drop above this item. 1.137 + dropPoint.ip = new InsertionPoint( 1.138 + PlacesUtils.getConcreteItemId(resultNode), 1.139 + -1, 1.140 + Ci.nsITreeView.DROP_BEFORE, 1.141 + PlacesUtils.nodeIsTagQuery(elt._placesNode), 1.142 + elt._placesNode.itemId); 1.143 + return dropPoint; 1.144 + } 1.145 + 1.146 + // Drop below the item. 1.147 + dropPoint.ip = new InsertionPoint( 1.148 + PlacesUtils.getConcreteItemId(resultNode), 1.149 + -1, 1.150 + Ci.nsITreeView.DROP_AFTER, 1.151 + PlacesUtils.nodeIsTagQuery(elt._placesNode), 1.152 + elt._placesNode.itemId); 1.153 + return dropPoint; 1.154 + ]]></body> 1.155 + </method> 1.156 + 1.157 + <!-- Sub-menus should be opened when the mouse drags over them, and closed 1.158 + when the mouse drags off. The overFolder object manages opening and 1.159 + closing of folders when the mouse hovers. --> 1.160 + <field name="_overFolder"><![CDATA[({ 1.161 + _self: this, 1.162 + _folder: {elt: null, 1.163 + openTimer: null, 1.164 + hoverTime: 350, 1.165 + closeTimer: null}, 1.166 + _closeMenuTimer: null, 1.167 + 1.168 + get elt() { 1.169 + return this._folder.elt; 1.170 + }, 1.171 + set elt(val) { 1.172 + return this._folder.elt = val; 1.173 + }, 1.174 + 1.175 + get openTimer() { 1.176 + return this._folder.openTimer; 1.177 + }, 1.178 + set openTimer(val) { 1.179 + return this._folder.openTimer = val; 1.180 + }, 1.181 + 1.182 + get hoverTime() { 1.183 + return this._folder.hoverTime; 1.184 + }, 1.185 + set hoverTime(val) { 1.186 + return this._folder.hoverTime = val; 1.187 + }, 1.188 + 1.189 + get closeTimer() { 1.190 + return this._folder.closeTimer; 1.191 + }, 1.192 + set closeTimer(val) { 1.193 + return this._folder.closeTimer = val; 1.194 + }, 1.195 + 1.196 + get closeMenuTimer() { 1.197 + return this._closeMenuTimer; 1.198 + }, 1.199 + set closeMenuTimer(val) { 1.200 + return this._closeMenuTimer = val; 1.201 + }, 1.202 + 1.203 + setTimer: function OF__setTimer(aTime) { 1.204 + var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 1.205 + timer.initWithCallback(this, aTime, timer.TYPE_ONE_SHOT); 1.206 + return timer; 1.207 + }, 1.208 + 1.209 + notify: function OF__notify(aTimer) { 1.210 + // Function to process all timer notifications. 1.211 + 1.212 + if (aTimer == this._folder.openTimer) { 1.213 + // Timer to open a submenu that's being dragged over. 1.214 + this._folder.elt.lastChild.setAttribute("autoopened", "true"); 1.215 + this._folder.elt.lastChild.showPopup(this._folder.elt); 1.216 + this._folder.openTimer = null; 1.217 + } 1.218 + 1.219 + else if (aTimer == this._folder.closeTimer) { 1.220 + // Timer to close a submenu that's been dragged off of. 1.221 + // Only close the submenu if the mouse isn't being dragged over any 1.222 + // of its child menus. 1.223 + var draggingOverChild = PlacesControllerDragHelper 1.224 + .draggingOverChildNode(this._folder.elt); 1.225 + if (draggingOverChild) 1.226 + this._folder.elt = null; 1.227 + this.clear(); 1.228 + 1.229 + // Close any parent folders which aren't being dragged over. 1.230 + // (This is necessary because of the above code that keeps a folder 1.231 + // open while its children are being dragged over.) 1.232 + if (!draggingOverChild) 1.233 + this.closeParentMenus(); 1.234 + } 1.235 + 1.236 + else if (aTimer == this.closeMenuTimer) { 1.237 + // Timer to close this menu after the drag exit. 1.238 + var popup = this._self; 1.239 + // if we are no more dragging we can leave the menu open to allow 1.240 + // for better D&D bookmark organization 1.241 + if (PlacesControllerDragHelper.getSession() && 1.242 + !PlacesControllerDragHelper.draggingOverChildNode(popup.parentNode)) { 1.243 + popup.hidePopup(); 1.244 + // Close any parent menus that aren't being dragged over; 1.245 + // otherwise they'll stay open because they couldn't close 1.246 + // while this menu was being dragged over. 1.247 + this.closeParentMenus(); 1.248 + } 1.249 + this._closeMenuTimer = null; 1.250 + } 1.251 + }, 1.252 + 1.253 + // Helper function to close all parent menus of this menu, 1.254 + // as long as none of the parent's children are currently being 1.255 + // dragged over. 1.256 + closeParentMenus: function OF__closeParentMenus() { 1.257 + var popup = this._self; 1.258 + var parent = popup.parentNode; 1.259 + while (parent) { 1.260 + if (parent.localName == "menupopup" && parent._placesNode) { 1.261 + if (PlacesControllerDragHelper.draggingOverChildNode(parent.parentNode)) 1.262 + break; 1.263 + parent.hidePopup(); 1.264 + } 1.265 + parent = parent.parentNode; 1.266 + } 1.267 + }, 1.268 + 1.269 + // The mouse is no longer dragging over the stored menubutton. 1.270 + // Close the menubutton, clear out drag styles, and clear all 1.271 + // timers for opening/closing it. 1.272 + clear: function OF__clear() { 1.273 + if (this._folder.elt && this._folder.elt.lastChild) { 1.274 + if (!this._folder.elt.lastChild.hasAttribute("dragover")) 1.275 + this._folder.elt.lastChild.hidePopup(); 1.276 + // remove menuactive style 1.277 + this._folder.elt.removeAttribute("_moz-menuactive"); 1.278 + this._folder.elt = null; 1.279 + } 1.280 + if (this._folder.openTimer) { 1.281 + this._folder.openTimer.cancel(); 1.282 + this._folder.openTimer = null; 1.283 + } 1.284 + if (this._folder.closeTimer) { 1.285 + this._folder.closeTimer.cancel(); 1.286 + this._folder.closeTimer = null; 1.287 + } 1.288 + } 1.289 + })]]></field> 1.290 + 1.291 + <method name="_cleanupDragDetails"> 1.292 + <body><![CDATA[ 1.293 + // Called on dragend and drop. 1.294 + PlacesControllerDragHelper.currentDropTarget = null; 1.295 + this._rootView._draggedElt = null; 1.296 + this.removeAttribute("dragover"); 1.297 + this.removeAttribute("dragstart"); 1.298 + this._indicatorBar.hidden = true; 1.299 + ]]></body> 1.300 + </method> 1.301 + 1.302 + </implementation> 1.303 + 1.304 + <handlers> 1.305 + <handler event="DOMMenuItemActive"><![CDATA[ 1.306 + let elt = event.target; 1.307 + if (elt.parentNode != this) 1.308 + return; 1.309 + 1.310 +#ifdef XP_MACOSX 1.311 + // XXX: The following check is a temporary hack until bug 420033 is 1.312 + // resolved. 1.313 + let parentElt = elt.parent; 1.314 + while (parentElt) { 1.315 + if (parentElt.id == "bookmarksMenuPopup" || 1.316 + parentElt.id == "goPopup") 1.317 + return; 1.318 + 1.319 + parentElt = parentElt.parentNode; 1.320 + } 1.321 +#endif 1.322 + 1.323 + if (window.XULBrowserWindow) { 1.324 + let elt = event.target; 1.325 + let placesNode = elt._placesNode; 1.326 + 1.327 + var linkURI; 1.328 + if (placesNode && PlacesUtils.nodeIsURI(placesNode)) 1.329 + linkURI = placesNode.uri; 1.330 + else if (elt.hasAttribute("targetURI")) 1.331 + linkURI = elt.getAttribute("targetURI"); 1.332 + 1.333 + if (linkURI) 1.334 + window.XULBrowserWindow.setOverLink(linkURI, null); 1.335 + } 1.336 + ]]></handler> 1.337 + 1.338 + <handler event="DOMMenuItemInactive"><![CDATA[ 1.339 + let elt = event.target; 1.340 + if (elt.parentNode != this) 1.341 + return; 1.342 + 1.343 + if (window.XULBrowserWindow) 1.344 + window.XULBrowserWindow.setOverLink("", null); 1.345 + ]]></handler> 1.346 + 1.347 + <handler event="dragstart"><![CDATA[ 1.348 + if (!event.target._placesNode) 1.349 + return; 1.350 + 1.351 + let draggedElt = event.target._placesNode; 1.352 + 1.353 + // Force a copy action if parent node is a query or we are dragging a 1.354 + // not-removable node. 1.355 + if (!PlacesControllerDragHelper.canMoveNode(draggedElt)) 1.356 + event.dataTransfer.effectAllowed = "copyLink"; 1.357 + 1.358 + // Activate the view and cache the dragged element. 1.359 + this._rootView._draggedElt = draggedElt; 1.360 + this._rootView.controller.setDataTransfer(event); 1.361 + this.setAttribute("dragstart", "true"); 1.362 + event.stopPropagation(); 1.363 + ]]></handler> 1.364 + 1.365 + <handler event="drop"><![CDATA[ 1.366 + PlacesControllerDragHelper.currentDropTarget = event.target; 1.367 + 1.368 + let dropPoint = this._getDropPoint(event); 1.369 + if (dropPoint && dropPoint.ip) { 1.370 + PlacesControllerDragHelper.onDrop(dropPoint.ip, event.dataTransfer); 1.371 + event.preventDefault(); 1.372 + } 1.373 + 1.374 + this._cleanupDragDetails(); 1.375 + event.stopPropagation(); 1.376 + ]]></handler> 1.377 + 1.378 + <handler event="dragover"><![CDATA[ 1.379 + PlacesControllerDragHelper.currentDropTarget = event.target; 1.380 + let dt = event.dataTransfer; 1.381 + 1.382 + let dropPoint = this._getDropPoint(event); 1.383 + if (!dropPoint || !dropPoint.ip || 1.384 + !PlacesControllerDragHelper.canDrop(dropPoint.ip, dt)) { 1.385 + this._indicatorBar.hidden = true; 1.386 + event.stopPropagation(); 1.387 + return; 1.388 + } 1.389 + 1.390 + // Mark this popup as being dragged over. 1.391 + this.setAttribute("dragover", "true"); 1.392 + 1.393 + if (dropPoint.folderElt) { 1.394 + // We are dragging over a folder. 1.395 + // _overFolder should take the care of opening it on a timer. 1.396 + if (this._overFolder.elt && 1.397 + this._overFolder.elt != dropPoint.folderElt) { 1.398 + // We are dragging over a new folder, let's clear old values 1.399 + this._overFolder.clear(); 1.400 + } 1.401 + if (!this._overFolder.elt) { 1.402 + this._overFolder.elt = dropPoint.folderElt; 1.403 + // Create the timer to open this folder. 1.404 + this._overFolder.openTimer = this._overFolder 1.405 + .setTimer(this._overFolder.hoverTime); 1.406 + } 1.407 + // Since we are dropping into a folder set the corresponding style. 1.408 + dropPoint.folderElt.setAttribute("_moz-menuactive", true); 1.409 + } 1.410 + else { 1.411 + // We are not dragging over a folder. 1.412 + // Clear out old _overFolder information. 1.413 + this._overFolder.clear(); 1.414 + } 1.415 + 1.416 + // Autoscroll the popup strip if we drag over the scroll buttons. 1.417 + let anonid = event.originalTarget.getAttribute('anonid'); 1.418 + let scrollDir = anonid == "scrollbutton-up" ? -1 : 1.419 + anonid == "scrollbutton-down" ? 1 : 0; 1.420 + if (scrollDir != 0) { 1.421 + this._scrollBox.scrollByIndex(scrollDir, false); 1.422 + } 1.423 + 1.424 + // Check if we should hide the drop indicator for this target. 1.425 + if (dropPoint.folderElt || this._hideDropIndicator(event)) { 1.426 + this._indicatorBar.hidden = true; 1.427 + event.preventDefault(); 1.428 + event.stopPropagation(); 1.429 + return; 1.430 + } 1.431 + 1.432 + // We should display the drop indicator relative to the arrowscrollbox. 1.433 + let sbo = this._scrollBox.scrollBoxObject; 1.434 + let newMarginTop = 0; 1.435 + if (scrollDir == 0) { 1.436 + let elt = this.firstChild; 1.437 + while (elt && event.screenY > elt.boxObject.screenY + 1.438 + elt.boxObject.height / 2) 1.439 + elt = elt.nextSibling; 1.440 + newMarginTop = elt ? elt.boxObject.screenY - sbo.screenY : 1.441 + sbo.height; 1.442 + } 1.443 + else if (scrollDir == 1) 1.444 + newMarginTop = sbo.height; 1.445 + 1.446 + // Set the new marginTop based on arrowscrollbox. 1.447 + newMarginTop += sbo.y - this._scrollBox.boxObject.y; 1.448 + this._indicatorBar.firstChild.style.marginTop = newMarginTop + "px"; 1.449 + this._indicatorBar.hidden = false; 1.450 + 1.451 + event.preventDefault(); 1.452 + event.stopPropagation(); 1.453 + ]]></handler> 1.454 + 1.455 + <handler event="dragexit"><![CDATA[ 1.456 + PlacesControllerDragHelper.currentDropTarget = null; 1.457 + this.removeAttribute("dragover"); 1.458 + 1.459 + // If we have not moved to a valid new target clear the drop indicator 1.460 + // this happens when moving out of the popup. 1.461 + let target = event.relatedTarget; 1.462 + if (!target || !this.contains(target)) 1.463 + this._indicatorBar.hidden = true; 1.464 + 1.465 + // Close any folder being hovered over 1.466 + if (this._overFolder.elt) { 1.467 + this._overFolder.closeTimer = this._overFolder 1.468 + .setTimer(this._overFolder.hoverTime); 1.469 + } 1.470 + 1.471 + // The autoopened attribute is set when this folder was automatically 1.472 + // opened after the user dragged over it. If this attribute is set, 1.473 + // auto-close the folder on drag exit. 1.474 + // We should also try to close this popup if the drag has started 1.475 + // from here, the timer will check if we are dragging over a child. 1.476 + if (this.hasAttribute("autoopened") || 1.477 + this.hasAttribute("dragstart")) { 1.478 + this._overFolder.closeMenuTimer = this._overFolder 1.479 + .setTimer(this._overFolder.hoverTime); 1.480 + } 1.481 + 1.482 + event.stopPropagation(); 1.483 + ]]></handler> 1.484 + 1.485 + <handler event="dragend"><![CDATA[ 1.486 + this._cleanupDragDetails(); 1.487 + ]]></handler> 1.488 + 1.489 + </handlers> 1.490 + </binding> 1.491 + 1.492 + <!-- Most of this is copied from the arrowpanel binding in popup.xml --> 1.493 + <binding id="places-popup-arrow" 1.494 + extends="chrome://browser/content/places/menu.xml#places-popup-base"> 1.495 + <content flip="both" side="top" position="bottomcenter topright"> 1.496 + <xul:vbox anonid="container" class="panel-arrowcontainer" flex="1" 1.497 + xbl:inherits="side,panelopen"> 1.498 + <xul:box anonid="arrowbox" class="panel-arrowbox"> 1.499 + <xul:image anonid="arrow" class="panel-arrow" xbl:inherits="side"/> 1.500 + </xul:box> 1.501 + <xul:box class="panel-arrowcontent" xbl:inherits="side,align,dir,orient,pack" flex="1"> 1.502 + <xul:vbox class="menupopup-drop-indicator-bar" hidden="true"> 1.503 + <xul:image class="menupopup-drop-indicator" mousethrough="always"/> 1.504 + </xul:vbox> 1.505 + <xul:arrowscrollbox class="popup-internal-box" flex="1" orient="vertical" 1.506 + smoothscroll="false"> 1.507 + <children/> 1.508 + </xul:arrowscrollbox> 1.509 + </xul:box> 1.510 + </xul:vbox> 1.511 + </content> 1.512 + 1.513 + <implementation> 1.514 + <constructor><![CDATA[ 1.515 + this.style.pointerEvents = 'none'; 1.516 + ]]></constructor> 1.517 + <method name="adjustArrowPosition"> 1.518 + <body><![CDATA[ 1.519 + var arrow = document.getAnonymousElementByAttribute(this, "anonid", "arrow"); 1.520 + 1.521 + var anchor = this.anchorNode; 1.522 + if (!anchor) { 1.523 + arrow.hidden = true; 1.524 + return; 1.525 + } 1.526 + 1.527 + var container = document.getAnonymousElementByAttribute(this, "anonid", "container"); 1.528 + var arrowbox = document.getAnonymousElementByAttribute(this, "anonid", "arrowbox"); 1.529 + 1.530 + var position = this.alignmentPosition; 1.531 + var offset = this.alignmentOffset; 1.532 + 1.533 + // if this panel has a "sliding" arrow, we may have previously set margins... 1.534 + arrowbox.style.removeProperty("transform"); 1.535 + if (position.indexOf("start_") == 0 || position.indexOf("end_") == 0) { 1.536 + container.orient = "horizontal"; 1.537 + arrowbox.orient = "vertical"; 1.538 + if (position.indexOf("_after") > 0) { 1.539 + arrowbox.pack = "end"; 1.540 + } else { 1.541 + arrowbox.pack = "start"; 1.542 + } 1.543 + arrowbox.style.transform = "translate(0, " + -offset + "px)"; 1.544 + 1.545 + // The assigned side stays the same regardless of direction. 1.546 + var isRTL = (window.getComputedStyle(this).direction == "rtl"); 1.547 + 1.548 + if (position.indexOf("start_") == 0) { 1.549 + container.dir = "reverse"; 1.550 + this.setAttribute("side", isRTL ? "left" : "right"); 1.551 + } 1.552 + else { 1.553 + container.dir = ""; 1.554 + this.setAttribute("side", isRTL ? "right" : "left"); 1.555 + } 1.556 + } 1.557 + else if (position.indexOf("before_") == 0 || position.indexOf("after_") == 0) { 1.558 + container.orient = ""; 1.559 + arrowbox.orient = ""; 1.560 + if (position.indexOf("_end") > 0) { 1.561 + arrowbox.pack = "end"; 1.562 + } else { 1.563 + arrowbox.pack = "start"; 1.564 + } 1.565 + arrowbox.style.transform = "translate(" + -offset + "px, 0)"; 1.566 + 1.567 + if (position.indexOf("before_") == 0) { 1.568 + container.dir = "reverse"; 1.569 + this.setAttribute("side", "bottom"); 1.570 + } 1.571 + else { 1.572 + container.dir = ""; 1.573 + this.setAttribute("side", "top"); 1.574 + } 1.575 + } 1.576 + 1.577 + arrow.hidden = false; 1.578 + ]]></body> 1.579 + </method> 1.580 + </implementation> 1.581 + 1.582 + <handlers> 1.583 + <handler event="popupshowing" phase="target"><![CDATA[ 1.584 + this.adjustArrowPosition(); 1.585 + ]]></handler> 1.586 + <handler event="popupshown" phase="target"><![CDATA[ 1.587 + this.setAttribute("panelopen", "true"); 1.588 + let disablePointerEvents; 1.589 + if (!this.hasAttribute("disablepointereventsfortransition")) { 1.590 + let container = document.getAnonymousElementByAttribute(this, "anonid", "container"); 1.591 + let cs = getComputedStyle(container); 1.592 + let transitionProp = cs.transitionProperty; 1.593 + let transitionTime = parseFloat(cs.transitionDuration); 1.594 + disablePointerEvents = (transitionProp.contains("transform") || 1.595 + transitionProp == "all") && 1.596 + transitionTime > 0; 1.597 + this.setAttribute("disablepointereventsfortransition", disablePointerEvents); 1.598 + } else { 1.599 + disablePointerEvents = this.getAttribute("disablepointereventsfortransition") == "true"; 1.600 + } 1.601 + if (!disablePointerEvents) { 1.602 + this.style.removeProperty("pointer-events"); 1.603 + } 1.604 + ]]></handler> 1.605 + <handler event="transitionend"><![CDATA[ 1.606 + if (event.originalTarget.getAttribute("anonid") == "container" && 1.607 + event.propertyName == "transform") { 1.608 + this.style.removeProperty("pointer-events"); 1.609 + } 1.610 + ]]></handler> 1.611 + <handler event="popuphidden" phase="target"><![CDATA[ 1.612 + this.removeAttribute("panelopen"); 1.613 + if (this.getAttribute("disablepointereventsfortransition") == "true") { 1.614 + this.style.pointerEvents = 'none'; 1.615 + } 1.616 + ]]></handler> 1.617 + </handlers> 1.618 + </binding> 1.619 +</bindings>