[Laszlo-checkins] r13086 - openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml

bargull@openlaszlo.org bargull at openlaszlo.org
Thu Feb 26 15:51:12 PST 2009


Author: bargull
Date: 2009-02-26 15:51:07 -0800 (Thu, 26 Feb 2009)
New Revision: 13086

Modified:
   openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js
   openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzMouseKernel.js
   openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js
Log:
Change 20090226-bargull-9sU by bargull at dell--p4--2-53 on 2009-02-26 15:13:35
    in /home/Admin/src/svn/openlaszlo/trunk
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: fix contextmenu (dhtml)

New Features:

Bugs Fixed: LPP-7661

Technical Reviewer: max
QA Reviewer: promanik
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
- remove direct calls to "__showContextMenu()" from LzSprite and LzInputTextSprite.
- remove "__updateContextMenuDiv()" which caused the last bug reported by Maynard

This is the new plan:
- use "document.elementFromPoint()" to retrieve the element under the mouse position
- if the element has got a context-menu, just show it
- otherwise hide the element and call "document.elementFromPoint()" again to get the next element
- repeat these steps until the canvas sprite is reached

Also added quirk "swf8_contextmenu" to emulate swf8 context-menu behaviour.
    

Tests:
testcases from bugreport in IE6, FF3, Saf3



Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js	2009-02-26 23:30:28 UTC (rev 13085)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzInputTextSprite.js	2009-02-26 23:51:07 UTC (rev 13086)
@@ -530,9 +530,6 @@
             return;
         }
         if (window['LzKeyboardKernel']) LzKeyboardKernel.__cancelKeys = false;
-        if (evt.button == 2) {
-            LzMouseKernel.__showContextMenu(this);
-        }
     } else if (eventname == 'onblur') {
         if (window['LzKeyboardKernel']) LzKeyboardKernel.__cancelKeys = true;
         if (LzInputTextSprite.prototype.__focusedSprite === sprite) {

Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzMouseKernel.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzMouseKernel.js	2009-02-26 23:30:28 UTC (rev 13085)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzMouseKernel.js	2009-02-26 23:51:07 UTC (rev 13086)
@@ -42,7 +42,7 @@
         if (e.button == 2 && eventname != 'oncontextmenu') return;
         if (eventname == 'oncontextmenu') {
             if (targ && targ.owner) {
-                return LzMouseKernel.__showContextMenu(targ.owner);
+                return LzMouseKernel.__showContextMenu(e);
             }
         } else {
             LzMouseKernel.__sendEvent(eventname);
@@ -188,24 +188,65 @@
         }
         LzMouseKernel.__sendEvent('onmousemove');
     }
-    ,__showContextMenu: function(sprite) {
+    ,__showContextMenu: function(e) {
         // show the default menu if not found...
         var cmenu = LzSprite.__rootSprite.__contextmenu;
-        // walk up the parent chain looking for a __contextmenu
-        while (sprite.__parent) {
-            if (sprite.__contextmenu) {
-                // check mouse bounds
-                var mpos = sprite.getMouse();
-                //Debug.write('pos', mpos, sprite.width, sprite.height);
-                if (mpos.x >= 0 && mpos.x < sprite.width &&
-                    mpos.y >= 0 && mpos.y < sprite.height) {
-                    cmenu = sprite.__contextmenu;
+        if (document.elementFromPoint) {
+            var swf8mode = LzSprite.prototype.quirks.swf8_contextmenu;
+            var x = (e.pageX || e.clientX || 0);
+            var y = (e.pageY || e.clientY || 0);
+            // update mouse position, required for Safari
+            LzMouseKernel.__x = x;
+            LzMouseKernel.__y = y;
+            var rootdiv = canvas.sprite.__LZdiv;
+            var arr = [];
+            do {
+                var elem = document.elementFromPoint(x, y);
+                var owner = elem.owner;
+                if (! owner) {
+                    // owner property is required
                     break;
+                } else if (owner.__contextmenu) {
+                    // found a contextmenu
+                    cmenu = owner.__contextmenu;
+                    break;
+                } else if (swf8mode && ((owner.__LZdiv === elem && owner.bgcolor != null)
+                                || owner instanceof LzTextSprite)) {
+                    // swf8 compatibility: movieclips with bgcolor and textfields
+                    // don't pass through context-menu
+                    break;
+                } else {
+                    // hide this element to get next layer
+                    arr.push(elem, elem.style.display);
+                    elem.style.display = 'none';
                 }
+            } while (elem !== rootdiv);
+
+            // restore display
+            for (var i = arr.length - 1; i >= 0; i -= 2) {
+                arr[i - 1].style.display = arr[i];
             }
-            sprite = sprite.__parent;
+        } else {
+            // this is less reliable compared to elementFromPoint..
+            var sprite = (e.srcElement || e.target).owner;
+            if (sprite) {
+                // walk up the parent chain looking for a __contextmenu
+                while (sprite.__parent) {
+                    if (sprite.__contextmenu) {
+                        // check mouse bounds
+                        var mpos = sprite.getMouse();
+                        //Debug.write('pos', mpos, sprite.width, sprite.height);
+                        if (mpos.x >= 0 && mpos.x < sprite.width &&
+                            mpos.y >= 0 && mpos.y < sprite.height) {
+                            cmenu = sprite.__contextmenu;
+                            break;
+                        }
+                    }
+                    sprite = sprite.__parent;
+                }
+            }
         }
-        //Debug.warn('__showContextMenu', sprite);
+
         if (cmenu) {
             cmenu.kernel.__show();
             return cmenu.kernel.showbuiltins;

Modified: openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js	2009-02-26 23:30:28 UTC (rev 13085)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/kernel/dhtml/LzSprite.js	2009-02-26 23:51:07 UTC (rev 13086)
@@ -364,6 +364,7 @@
     ,use_css_sprites: true
     ,preload_images: true
     ,inputtext_strips_newlines: false
+    ,swf8_contextmenu: true
 }
 
 LzSprite.prototype.capabilities = {
@@ -1001,12 +1002,6 @@
     if (window['LzInputTextSprite'] && eventname == 'onmouseover' && LzInputTextSprite.prototype.__lastshown != null) LzInputTextSprite.prototype.__hideIfNotFocused();
 
     if (eventname == 'onmousedown') {
-        if (e.button == 2) {
-            LzMouseKernel.__showContextMenu(this);
-            // setting cancelBubble doesn't help with window.oncontextmenu events not being sent for clickable sprites with a null default context menu - see LPP-7661
-            e.cancelBubble = false;
-            return true;
-        }
         // cancel mousedown event bubbling...
         e.cancelBubble = true;
         this.__mouseisdown = true;
@@ -1107,7 +1102,6 @@
         if (this.clip) this.__updateClip();
         if (this.stretches) this.__updateStretches();
         if (this.__LZclick) this.__LZclick.style.width = w;
-        if (this.__contextmenu) this.__updateContextMenuDiv();
         return w;
     }
 }
@@ -1139,7 +1133,6 @@
         if (this.clip) this.__updateClip();
         if (this.stretches) this.__updateStretches();
         if (this.__LZclick) this.__LZclick.style.height = h;
-        if (this.__contextmenu) this.__updateContextMenuDiv();
         return h;
     }
 }
@@ -2100,26 +2093,10 @@
   * @param LzContextMenu cmenu: LzContextMenu to install on this view
   */
 LzSprite.prototype.setContextMenu = function( cmenu ){
-    //this.setClickable(true);
-    this.__updateContextMenuDiv();
     this.__contextmenu = cmenu;
 }
 
 /**
-  * Update the size of the div that will catch context menu events. 
-  * @access private
-  */
-LzSprite.prototype.__updateContextMenuDiv = function() {
-    if (! this.isroot) {
-        // Use the the scrolldiv if present (text/inputtext) or the click div 
-        // container (__LZclickcontainerdiv)
-        var div = this.scrolldiv ? this.scrolldiv : this.__LZclickcontainerdiv;
-        div.style.width = this.__LZdiv.style.width;
-        div.style.height = this.__LZdiv.style.height;
-    }
-}
-
-/**
   * LzView.getContextMenu
   * Return the current context menu
   */



More information about the Laszlo-checkins mailing list