소스 검색

Can now set client to lazy load pages which will wait for all resources on the page to load before rendering - https://github.com/jonnnnyw/php-phantomjs/issues/85

Jonny Wenmoth 9 년 전
부모
커밋
384b6dbeab

+ 11 - 0
src/JonnyW/PhantomJs/Client.php

@@ -208,4 +208,15 @@ class Client implements ClientInterface
     {
         return $this->procedureCompiler;
     }
+
+    /**
+     * Set lazy request flag.
+     *
+     * @access public
+     * @return void
+     */
+    public function isLazy()
+    {
+        $this->procedure = 'http_lazy';
+    }
 }

+ 8 - 0
src/JonnyW/PhantomJs/ClientInterface.php

@@ -83,4 +83,12 @@ interface ClientInterface
      * @return string
      */
     public function getProcedure();
+
+    /**
+     * Set lazy request flag.
+     *
+     * @access public
+     * @return void
+     */
+    public function isLazy();
 }

+ 6 - 6
src/JonnyW/PhantomJs/Http/AbstractRequest.php

@@ -103,12 +103,12 @@ abstract class AbstractRequest
      */
     public function __construct($url = null, $method = RequestInterface::METHOD_GET, $timeout = 5000)
     {
-        $this->headers        = array();
-        $this->data           = array();
-        $this->bodyStyles     = array();
-        $this->delay          = 0;
-        $this->viewportWidth  = 0;
-        $this->viewportHeight = 0;
+        $this->headers         = array();
+        $this->data            = array();
+        $this->bodyStyles      = array();
+        $this->delay           = 0;
+        $this->viewportWidth   = 0;
+        $this->viewportHeight  = 0;
 
         $this->setMethod($method);
         $this->setTimeout($timeout);

+ 7 - 0
src/JonnyW/PhantomJs/Resources/procedures/http_default.proc

@@ -50,6 +50,13 @@ page.onResourceTimeout = function (error) {
     [[ engine.load('page_on_resource_timeout') ]]
 };
 
+/**
+ * On resource requested
+ */
+page.onResourceRequested = function (resource) {
+    [[ engine.load('page_on_resource_requested') ]]
+};
+
 /**
  * On resource received
  */

+ 125 - 0
src/JonnyW/PhantomJs/Resources/procedures/http_lazy.proc

@@ -0,0 +1,125 @@
+
+[% autoescape false %]
+{% autoescape false %}
+
+/**
+ * Set up page and script parameters
+ */
+var page       = require('webpage').create(),
+    system     = require('system'),
+    response   = {},
+    debug      = [],
+    logs       = [],
+    procedure  = {},
+    resources  = 0,
+    timeout;
+
+/**
+ * Global variables
+ */
+[[ engine.load('global_variables') ]]
+
+/**
+ * Define width & height of capture
+ */
+[[ engine.load('page_clip_rect') ]]
+
+/**
+ * Define paper size.
+ */
+[[ engine.load('page_paper_size') ]]
+
+/**
+ * Define viewport size.
+ */
+[[ engine.load('page_viewport_size') ]]
+
+
+/**
+ * Define custom headers.
+ */
+[[ engine.load('page_custom_headers') ]]
+
+/**
+ * Page settings
+ */
+[[ engine.load('page_settings') ]]
+
+/**
+ * On resource timeout
+ */
+page.onResourceTimeout = function (error) {
+    [[ engine.load('page_on_resource_timeout') ]]
+};
+
+/**
+ * On resource requested
+ */
+page.onResourceRequested = function (req) {
+    
+    [[ engine.load('page_on_resource_requested') ]]
+    
+    resources++;
+    window.clearTimeout(timeout);
+    
+    debug.push(new Date().toISOString().slice(0, -5) + ' [INFO] PhantomJS - Resource requested (' + req.url + ')');
+};
+
+/**
+ * On resource received
+ */
+page.onResourceReceived = function (res) {
+    
+    var resource = res; // To be removed in version 5.0
+    
+    [[ engine.load('page_on_resource_received') ]]
+    
+    if(!res.stage || res.stage === 'end') {
+        
+        resources--;
+        debug.push(new Date().toISOString().slice(0, -5) + ' [INFO] PhantomJS - Resource received (' + res.url + ') ~ ' + res.status);
+        
+        if (resources === 0) {
+            
+            timeout = window.setTimeout(function() {
+                procedure.execute('success');
+            }, 300);
+        }
+    }
+};
+
+/**
+ * Handle page errors
+ */
+page.onError = function (msg, trace) {
+    [[ engine.load('page_on_error') ]]
+};
+
+/**
+ * Handle global errors
+ */
+phantom.onError = function(msg, trace) {
+    [[ engine.load('phantom_on_error') ]]
+};
+
+/**
+ * Open page
+ */
+page.open ('{{ input.getUrl() }}', '{{ input.getMethod() }}', '{{ input.getBody() }}', function (status) {
+    
+    [[ engine.load('page_body_styles') ]]
+
+    window.setTimeout(function () { 
+        procedure.execute(status); 
+    }, {{ input.getTimeout() - 200 }});
+});
+
+/**
+ * Execute procedure
+ */
+procedure.execute = function (status) {
+    [[ engine.load( 'procedure_' ~ procedure_type ) ]]
+};
+
+{% endautoescape %}
+[% endautoescape %]

+ 2 - 0
src/JonnyW/PhantomJs/Resources/procedures/page_on_resource_requested.partial

@@ -0,0 +1,2 @@
+
+

+ 49 - 0
src/JonnyW/PhantomJs/Tests/Integration/ClientTest.php

@@ -837,6 +837,55 @@ EOF;
         $this->assertSame(($startTime+$delay), $endTime);
     }
 
+    /**
+     * Test lazy request returns content after
+     * all resources are loaded
+     *
+     * @access public
+     * @return void
+     */
+    public function testLazyRequestReturnsResourcesAfterAllResourcesAreLoaded()
+    {
+        $client = $this->getClient();
+        $client->isLazy();
+
+        $request  = $client->getMessageFactory()->createRequest();
+        $response = $client->getMessageFactory()->createResponse();
+
+        $request->setMethod('GET');
+        $request->setUrl('http://jonnyw.kiwi/tests/test-lazy.php');
+        $request->setTimeout(5000);
+
+        $client->send($request, $response);
+
+        $this->assertContains('<p id="content">loaded</p>', $response->getContent());
+    }
+
+    /**
+     * Test content is returned for lazy request
+     * if timeout is reached before resource is
+     * loaded
+     *
+     * @access public
+     * @return void
+     */
+    public function testContentIsReturnedForLazyRequestIfTimeoutIsReachedBeforeResourceIsLoaded()
+    {
+        $client = $this->getClient();
+        $client->isLazy();
+
+        $request  = $client->getMessageFactory()->createRequest();
+        $response = $client->getMessageFactory()->createResponse();
+
+        $request->setMethod('GET');
+        $request->setUrl('http://jonnyw.kiwi/tests/test-lazy.php');
+        $request->setTimeout(1000);
+
+        $client->send($request, $response);
+
+        $this->assertContains('<p id="content"></p>', $response->getContent());
+    }
+
     /**
      * Test debug logs debug info to
      * client log.