Jackmcbarn has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/169983

Change subject: Expose all ancestor frames
......................................................................

Expose all ancestor frames

The original reason for not exposing all ancestor frames was to protect
the empty-frame expansion cache. However, the way that cache works was
changed a while ago in I621e9075, and it's now safe to allow accessing all
ancestor frames. This has been requested on-wiki for a long time.

Change-Id: I2a26b583fb5c0347284ca753b15c0ab814618538
---
M engines/LuaCommon/LuaCommon.php
M engines/LuaCommon/lualib/mw.lua
M tests/engines/LuaCommon/luaParserTests.txt
3 files changed, 80 insertions(+), 15 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Scribunto 
refs/changes/83/169983/1

diff --git a/engines/LuaCommon/LuaCommon.php b/engines/LuaCommon/LuaCommon.php
index 6d4b841..8ce7538 100644
--- a/engines/LuaCommon/LuaCommon.php
+++ b/engines/LuaCommon/LuaCommon.php
@@ -40,6 +40,7 @@
         * @var array
         */
        protected $currentFrames = array();
+       protected $parentFrames = array();
        protected $expandCache = array();
        protected $availableLibraries = array();
        protected $loadedLibraries = array();
@@ -96,6 +97,7 @@
                                'loadPHPLibrary',
                                'frameExists',
                                'newChildFrame',
+                               'getParentFrame',
                                'getExpandedArgument',
                                'getAllExpandedArguments',
                                'expandTemplate',
@@ -207,17 +209,22 @@
                        $frame = 
$this->getParser()->getPreprocessor()->newFrame();
                }
 
-               $oldFrames = $this->currentFrames;
-               $this->currentFrames = array(
-                       'current' => $frame,
-                       'parent' => isset( $frame->parent ) ? $frame->parent : 
null,
-               );
+               $oldCurrentFrames = $this->currentFrames;
+               $oldParentFrames = $this->parentFrames;
+               $oldExpandCache = $this->expandCache;
+               $this->currentFrames = array( 'current' => $frame );
+               $this->parentFrames = array();
+               $this->expandCache = array();
 
                // @todo Once support for PHP 5.3 is dropped, lose $ref and 
just use
                // $this->currentFrames directly in the callback.
                $ref = &$this->currentFrames;
-               return new ScopedCallback( function () use ( &$ref, $oldFrames 
) {
-                       $ref = $oldFrames;
+               $ref2 = &$this->parentFrames;
+               $ref3 = &$this->expandCache;
+               return new ScopedCallback( function () use ( &$ref, &$ref2, 
&$ref3, $oldCurrentFrames, $oldParentFrames, $oldExpandCache ) {
+                       $ref = $oldCurrentFrames;
+                       $ref2 = $oldParentFrames;
+                       $ref3 = $oldExpandCache;
                } );
        }
 
@@ -555,6 +562,31 @@
                $newFrame = $frame->newChild( $args, $title );
                $newFrameId = 'frame' . count( $this->currentFrames );
                $this->currentFrames[$newFrameId] = $newFrame;
+               $this->parentFrames[$newFrameId] = $frameId;
+               return array( $newFrameId );
+       }
+
+       /**
+        * Handler for getParent()
+        *
+        * @param $frameId
+        * @return array
+        */
+       function getParentFrame( $frameId ) {
+               // no need to check the cap of 100 new frames in this function, 
since
+               // it doesn't actually create any frames
+
+               if ( isset( $this->parentFrames[$frameId] ) ) {
+                       return array( $this->parentFrames[$frameId] );
+               }
+               $frame = $this->getFrameById( $frameId );
+               if ( !isset( $frame->parent ) ) {
+                       $this->parentFrames[$frameId] = null;
+                       return array( null );
+               }
+               $newFrameId = 'frame' . count( $this->currentFrames );
+               $this->currentFrames[$newFrameId] = $frame->parent;
+               $this->parentFrames[$frameId] = $newFrameId;
                return array( $newFrameId );
        }
 
@@ -638,6 +670,7 @@
                $newFrame = $frame->newChild( $fargs, $finalTitle );
                $text = $this->doCachedExpansion( $newFrame, $dom,
                        array(
+                               'frameId' => $frameId,
                                'template' => $finalTitle->getPrefixedDBkey(),
                                'args' => $args
                        ) );
@@ -750,8 +783,8 @@
 
                $text = $this->doCachedExpansion( $frame, $text,
                        array(
+                               'frameId' => $frameId,
                                'inputText' => $text,
-                               'args' => $args,
                        ) );
                return array( $text );
        }
diff --git a/engines/LuaCommon/lualib/mw.lua b/engines/LuaCommon/lualib/mw.lua
index 06a670c..d0728c5 100644
--- a/engines/LuaCommon/lualib/mw.lua
+++ b/engines/LuaCommon/lualib/mw.lua
@@ -121,13 +121,12 @@
        return os.time( t )
 end
 
-local function newFrame( frameId, ... )
+local function newFrame( frameId )
        if not php.frameExists( frameId ) then
                return nil
        end
 
        local frame = {}
-       local parentFrameIds = { ... }
        local argCache = {}
        local argNames
        local args_mt = {}
@@ -228,7 +227,10 @@
        function frame:getParent()
                checkSelf( self, 'getParent' )
 
-               return newFrame( unpack( parentFrameIds ) )
+               local parentId = php.getParentFrame( frameId )
+               if parentId then
+                       return newFrame( parentId )
+               end
        end
 
        function frame:newChild( opt )
@@ -267,7 +269,7 @@
                end
 
                local newFrameId = php.newChildFrame( frameId, title, args )
-               return newFrame( newFrameId, frameId, unpack( parentFrameIds ) )
+               return newFrame( newFrameId )
        end
 
        function frame:expandTemplate( opt )
@@ -474,7 +476,7 @@
 
        local oldFrame = currentFrame
        if not currentFrame then
-               currentFrame = newFrame( 'current', 'parent' )
+               currentFrame = newFrame( 'current' )
        end
        local res = chunk()
        currentFrame = oldFrame
@@ -489,7 +491,7 @@
 end
 
 function mw.executeFunction( chunk )
-       local frame = newFrame( 'current', 'parent' )
+       local frame = newFrame( 'current' )
        local oldFrame = currentFrame
 
        if executeFunctionDepth == 0 then
@@ -628,7 +630,7 @@
 
 function mw.getCurrentFrame()
        if not currentFrame then
-               currentFrame = newFrame( 'current', 'parent' )
+               currentFrame = newFrame( 'current' )
        end
        return currentFrame
 end
diff --git a/tests/engines/LuaCommon/luaParserTests.txt 
b/tests/engines/LuaCommon/luaParserTests.txt
index ba9741d..7096e1a 100644
--- a/tests/engines/LuaCommon/luaParserTests.txt
+++ b/tests/engines/LuaCommon/luaParserTests.txt
@@ -155,6 +155,15 @@
        return mw.html.create( 'div' ):css( 'color', frame.args[1] )
 end
 
+function p.testAncestorFrames( frame )
+       local retval = {}
+       repeat
+               table.insert( retval, frame:getTitle() )
+               frame = frame:getParent()
+       until not frame
+       return table.concat( retval, ', ' )
+end
+
 return p
 !! endarticle
 
@@ -213,6 +222,18 @@
 Template:Scribunto_template_with_headers
 !! text
 == bar ==
+!! endarticle
+
+!! article
+Template:Wrapper1
+!! text
+{{#invoke:test|testAncestorFrames}}
+!! endarticle
+
+!! article
+Template:Wrapper2
+!! text
+{{Wrapper1}}
 !! endarticle
 
 !! test
@@ -487,3 +508,12 @@
 <div style="color:#ff0000"></div>
 
 !! end
+
+!! test
+Scribunto: Access to ancestor frames
+!! input
+{{Wrapper2}}
+!! result
+<p>Module:Test, Template:Wrapper1, Template:Wrapper2, Parser test
+</p>
+!! end

-- 
To view, visit https://gerrit.wikimedia.org/r/169983
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2a26b583fb5c0347284ca753b15c0ab814618538
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Scribunto
Gerrit-Branch: master
Gerrit-Owner: Jackmcbarn <jackmcb...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to