diff options
-rw-r--r-- | CHANGELOG.md | 4 | ||||
-rw-r--r-- | js/piwik.js | 17 | ||||
-rw-r--r-- | piwik.js | 4 | ||||
-rw-r--r-- | tests/javascript/index.php | 100 |
4 files changed, 120 insertions, 5 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d70ab9f3a..4be76cf395 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ This is a changelog for Piwik platform developers. All changes for our HTTP API' * `Tracker.recordEcommerceGoal` * `Tracker.recordStandardGoals` +### New APIs + +* The JavaScript Tracker `piwik.js` got a new method `logAllContentBlocksOnPage` to log all found content blocks within a page to the console. This is useful to debug / test content tracking. It can be triggered via `_paq.push(['logAllContentBlocksOnPage'])` + ### Internal Change * The option `branch` of the console command `development:sync-system-test-processed` was removed as it is no longer needed. diff --git a/js/piwik.js b/js/piwik.js index b568d541a0..9d012d6941 100644 --- a/js/piwik.js +++ b/js/piwik.js @@ -455,7 +455,7 @@ if (typeof JSON2 !== 'object') { getTrackedContentImpressions, getCurrentlyVisibleContentImpressionsRequestsIfNotTrackedYet, contentInteractionTrackingSetupDone, contains, match, pathname, piece, trackContentInteractionNode, trackContentInteractionNode, trackContentImpressionsWithinNode, trackContentImpression, - enableTrackOnlyVisibleContent, trackContentInteraction, clearEnableTrackOnlyVisibleContent, + enableTrackOnlyVisibleContent, trackContentInteraction, clearEnableTrackOnlyVisibleContent, logAllContentBlocksOnPage, trackVisibleContentImpressions, isTrackOnlyVisibleContentEnabled, port, isUrlToCurrentDomain, isNodeAuthorizedToTriggerInteraction, replaceHrefIfInternalLink, getConfigDownloadExtensions, disableLinkTracking, substr, setAnyAttribute, wasContentTargetAttrReplaced, max, abs, childNodes, compareDocumentPosition, body, @@ -474,6 +474,7 @@ if (typeof JSON2 !== 'object') { /*members amd */ /*global console:true */ /*members error */ +/*members log */ // asynchronous tracker (or proxy) if (typeof _paq !== 'object') { @@ -5319,6 +5320,20 @@ if (typeof Piwik !== 'object') { }, /** + * Useful to debug content tracking. This method will log all detected content blocks to console + * (if the browser supports the console). It will list the detected name, piece, and target of each + * content block. + */ + logAllContentBlocksOnPage: function () { + var contentNodes = content.findContentNodes(); + var contents = content.collectContent(contentNodes); + + if (console !== undefined && console && console.log) { + console.log(contents); + } + }, + + /** * Records an event * * @param string category The Event Category (Videos, Music, Games...) @@ -48,8 +48,8 @@ case 2:return"middle";case 3:return"right"}}function cb(cq){return cq.target||cq if(cs==="visit"||cs===2){aa();ah[cr]=ct}else{if(cs==="page"||cs===3){bq[cr]=ct}else{if(cs==="event"){ac[cr]=ct}}}}},getCustomVariable:function(cr,cs){var cq;if(!x(cs)){cs="visit"}if(cs==="page"||cs===3){cq=bq[cr]}else{if(cs==="event"){cq=ac[cr]}else{if(cs==="visit"||cs===2){aa();cq=ah[cr]}}}if(!x(cq)||(cq&&cq[0]==="")){return false}return cq},deleteCustomVariable:function(cq,cr){if(this.getCustomVariable(cq,cr)){this.setCustomVariable(cq,"","",cr)}},storeCustomVariablesInCookie:function(){bc=true},setLinkTrackingTimer:function(cq){bz=cq},setDownloadExtensions:function(cq){if(o(cq)){cq=cq.split("|")}aZ=cq},addDownloadExtensions:function(cr){var cq;if(o(cr)){cr=cr.split("|")}for(cq=0;cq<cr.length;cq++){aZ.push(cr[cq])}},removeDownloadExtensions:function(cs){var cr,cq=[];if(o(cs)){cs=cs.split("|")}for(cr=0;cr<aZ.length;cr++){if(A(cs,aZ[cr])===-1){cq.push(aZ[cr])}}aZ=cq},setDomains:function(cq){bB=o(cq)?[cq]:cq;bB.push(bY)},setIgnoreClasses:function(cq){aj=o(cq)?[cq]:cq},setRequestMethod:function(cq){bE=cq||bC },setRequestContentType:function(cq){aP=cq||bj},setReferrerUrl:function(cq){bG=cq},setCustomUrl:function(cq){bd=bX(cj,cq)},setDocumentTitle:function(cq){aX=cq},setAPIUrl:function(cq){az=cq},setDownloadClasses:function(cq){bp=o(cq)?[cq]:cq},setLinkClasses:function(cq){aH=o(cq)?[cq]:cq},setCampaignNameKey:function(cq){a3=o(cq)?[cq]:cq},setCampaignKeywordKey:function(cq){aU=o(cq)?[cq]:cq},discardHashTag:function(cq){al=cq},setCookieNamePrefix:function(cq){ch=cq;ah=at()},setCookieDomain:function(cq){var cr=z(cq);if(bn(cr)){ar=cr;bv()}},setCookiePath:function(cq){ci=cq;bv()},setVisitorCookieTimeout:function(cq){ay=cq*1000},setSessionCookieTimeout:function(cq){aE=cq*1000},setReferralCookieTimeout:function(cq){bh=cq*1000},setConversionAttributionFirstReferrer:function(cq){ba=cq},disableCookies:function(){ap=true;b6.cookie="0";if(b5){X()}},deleteCookies:function(){X()},setDoNotTrack:function(cr){var cq=e.doNotTrack||e.msDoNotTrack;b9=cr&&(cq==="yes"||cq==="1");if(b9){this.disableCookies()}},addListener:function(cr,cq){bL(cr,cq) },enableLinkTracking:function(cq){b7=true;if(q){bk(cq)}else{F.push(function(){bk(cq)})}},enableJSErrorTracking:function(){if(cn){return}cn=true;var cq=H.onerror;H.onerror=function(cv,ct,cs,cu,cr){aR(function(){var cw="JavaScript Errors";var cx=ct+":"+cs;if(cu){cx+=":"+cu}am(cw,cx,cv)});if(cq){return cq(cv,ct,cs,cu,cr)}return false}},disablePerformanceTracking:function(){a6=false},setGenerationTimeMs:function(cq){aM=parseInt(cq,10)},enableHeartBeatTimer:function(cq){cq=Math.max(cq,1);b3=(cq||15)*1000;if(bo!==null){bF()}},killFrame:function(){if(H.location!==H.top.location){H.top.location=H.location}},redirectFile:function(cq){if(H.location.protocol==="file:"){H.location=cq}},setCountPreRendered:function(cq){a5=cq},trackGoal:function(cq,cs,cr){aR(function(){bx(cq,cs,cr)})},trackLink:function(cr,cq,ct,cs){aR(function(){b0(cr,cq,ct,cs)})},trackPageView:function(cq,cr){ai=[];if(B(b5)){aR(function(){N(ab,az,b5)})}else{aR(function(){bl(cq,cr)})}},trackAllContentImpressions:function(){if(B(b5)){return -}aR(function(){aF(function(){var cq=n.findContentNodes();var cr=a1(cq);aq(cr,bz)})})},trackVisibleContentImpressions:function(cq,cr){if(B(b5)){return}if(!x(cq)){cq=true}if(!x(cr)){cr=750}bH(cq,cr,this);aR(function(){aV(function(){var cs=n.findContentNodes();var ct=bO(cs);aq(ct,bz)})})},trackContentImpression:function(cs,cq,cr){if(B(b5)){return}if(!cs){return}cq=cq||"Unknown";aR(function(){var ct=bZ(cs,cq,cr);a4(ct,bz)})},trackContentImpressionsWithinNode:function(cq){if(B(b5)||!cq){return}aR(function(){if(aB){aV(function(){var cr=n.findContentNodesWithinNode(cq);var cs=bO(cr);aq(cs,bz)})}else{aF(function(){var cr=n.findContentNodesWithinNode(cq);var cs=a1(cr);aq(cs,bz)})}})},trackContentInteraction:function(cs,ct,cq,cr){if(B(b5)){return}if(!cs||!ct){return}cq=cq||"Unknown";aR(function(){var cu=cl(cs,ct,cq,cr);a4(cu,bz)})},trackContentInteractionNode:function(cr,cq){if(B(b5)||!cr){return}aR(function(){var cs=a0(cr,cq);a4(cs,bz)})},trackEvent:function(cr,ct,cq,cs){aR(function(){am(cr,ct,cq,cs) -})},trackSiteSearch:function(cq,cs,cr){aR(function(){aS(cq,cs,cr)})},setEcommerceView:function(ct,cq,cs,cr){if(!x(cs)||!cs.length){cs=""}else{if(cs instanceof Array){cs=JSON2.stringify(cs)}}bq[5]=["_pkc",cs];if(x(cr)&&String(cr).length){bq[2]=["_pkp",cr]}if((!x(ct)||!ct.length)&&(!x(cq)||!cq.length)){return}if(x(ct)&&ct.length){bq[3]=["_pks",ct]}if(!x(cq)||!cq.length){cq=""}bq[4]=["_pkn",cq]},addEcommerceItem:function(cu,cq,cs,cr,ct){if(cu.length){bR[cu]=[cu,cq,cs,cr,ct]}},trackEcommerceOrder:function(cq,cu,ct,cs,cr,cv){bV(cq,cu,ct,cs,cr,cv)},trackEcommerceCartUpdate:function(cq){cg(cq)}}}function w(){return{push:S}}function b(ac,ab){var ad={};var Z,aa;for(Z=0;Z<ab.length;Z++){var X=ab[Z];ad[X]=1;for(aa=0;aa<ac.length;aa++){if(ac[aa]&&ac[aa][0]){var Y=ac[aa][0];if(X===Y){S(ac[aa]);delete ac[aa];if(ad[Y]>1){if(console!==undefined&&console&&console.error){console.error("The method "+Y+' is registered more than once in "paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers') +}aR(function(){aF(function(){var cq=n.findContentNodes();var cr=a1(cq);aq(cr,bz)})})},trackVisibleContentImpressions:function(cq,cr){if(B(b5)){return}if(!x(cq)){cq=true}if(!x(cr)){cr=750}bH(cq,cr,this);aR(function(){aV(function(){var cs=n.findContentNodes();var ct=bO(cs);aq(ct,bz)})})},trackContentImpression:function(cs,cq,cr){if(B(b5)){return}if(!cs){return}cq=cq||"Unknown";aR(function(){var ct=bZ(cs,cq,cr);a4(ct,bz)})},trackContentImpressionsWithinNode:function(cq){if(B(b5)||!cq){return}aR(function(){if(aB){aV(function(){var cr=n.findContentNodesWithinNode(cq);var cs=bO(cr);aq(cs,bz)})}else{aF(function(){var cr=n.findContentNodesWithinNode(cq);var cs=a1(cr);aq(cs,bz)})}})},trackContentInteraction:function(cs,ct,cq,cr){if(B(b5)){return}if(!cs||!ct){return}cq=cq||"Unknown";aR(function(){var cu=cl(cs,ct,cq,cr);a4(cu,bz)})},trackContentInteractionNode:function(cr,cq){if(B(b5)||!cr){return}aR(function(){var cs=a0(cr,cq);a4(cs,bz)})},logAllContentBlocksOnPage:function(){var cr=n.findContentNodes(); +var cq=n.collectContent(cr);if(console!==undefined&&console&&console.log){console.log(cq)}},trackEvent:function(cr,ct,cq,cs){aR(function(){am(cr,ct,cq,cs)})},trackSiteSearch:function(cq,cs,cr){aR(function(){aS(cq,cs,cr)})},setEcommerceView:function(ct,cq,cs,cr){if(!x(cs)||!cs.length){cs=""}else{if(cs instanceof Array){cs=JSON2.stringify(cs)}}bq[5]=["_pkc",cs];if(x(cr)&&String(cr).length){bq[2]=["_pkp",cr]}if((!x(ct)||!ct.length)&&(!x(cq)||!cq.length)){return}if(x(ct)&&ct.length){bq[3]=["_pks",ct]}if(!x(cq)||!cq.length){cq=""}bq[4]=["_pkn",cq]},addEcommerceItem:function(cu,cq,cs,cr,ct){if(cu.length){bR[cu]=[cu,cq,cs,cr,ct]}},trackEcommerceOrder:function(cq,cu,ct,cs,cr,cv){bV(cq,cu,ct,cs,cr,cv)},trackEcommerceCartUpdate:function(cq){cg(cq)}}}function w(){return{push:S}}function b(ac,ab){var ad={};var Z,aa;for(Z=0;Z<ab.length;Z++){var X=ab[Z];ad[X]=1;for(aa=0;aa<ac.length;aa++){if(ac[aa]&&ac[aa][0]){var Y=ac[aa][0];if(X===Y){S(ac[aa]);delete ac[aa];if(ad[Y]>1){if(console!==undefined&&console&&console.error){console.error("The method "+Y+' is registered more than once in "paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: http://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers') }}ad[Y]++}}}}return ac}W(H,"beforeunload",T,false);p();Date.prototype.getTimeAlias=Date.prototype.getTime;M=new E();var s=["disableCookies","setTrackerUrl","setAPIUrl","setCookiePath","setCookieDomain","setUserId","setSiteId","enableLinkTracking"];_paq=b(_paq,s);for(u=0;u<_paq.length;u++){if(_paq[u]){S(_paq[u])}}_paq=new w();d={addPlugin:function(X,Y){a[X]=Y},getTracker:function(X,Y){if(!x(Y)){Y=this.getAsyncTracker().getSiteId()}if(!x(X)){X=this.getAsyncTracker().getTrackerUrl()}return new E(X,Y)},getAsyncTracker:function(){return M}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return d})}return d}())}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{return eval("piwik_"+h)}catch(i){}return}var c,e=Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause"); if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}; /*! @license-end */ diff --git a/tests/javascript/index.php b/tests/javascript/index.php index 8c5179f77f..2664cb9239 100644 --- a/tests/javascript/index.php +++ b/tests/javascript/index.php @@ -1926,7 +1926,7 @@ function PiwikTest() { }); test("API methods", function() { - expect(65); + expect(66); equal( typeof Piwik.addPlugin, 'function', 'addPlugin' ); equal( typeof Piwik.getTracker, 'function', 'getTracker' ); @@ -1997,6 +1997,7 @@ function PiwikTest() { equal( typeof tracker.trackContentImpressionsWithinNode, 'function', 'trackContentImpressionsWithinNode' ); equal( typeof tracker.trackContentInteraction, 'function', 'trackContentInteraction' ); equal( typeof tracker.trackContentInteractionNode, 'function', 'trackContentInteractionNode' ); + equal( typeof tracker.logAllContentBlocksOnPage, 'function', 'logAllContentBlocksOnPage' ); // ecommerce equal( typeof tracker.setEcommerceView, 'function', 'setEcommerceView' ); equal( typeof tracker.addEcommerceItem, 'function', 'addEcommerceItem' ); @@ -3190,7 +3191,7 @@ if ($sqlite) { }); test("trackingContent", function() { - expect(81); + expect(83); function assertTrackingRequest(actual, expectedStartsWith, message) { @@ -3526,6 +3527,101 @@ if ($sqlite) { start(); }, 7000); + expected = + [ + { + "name": "My Ad 7", + "piece": "Unknown", + "target": "http://img7.example.com" + }, + { + "name": "http://www.example.com/path/xyz.jpg", + "piece": "http://www.example.com/path/xyz.jpg", + "target": "http://img6.example.com" + }, + { + "name": "My Ad 5", + "piece": "http://img5.example.com/path/xyz.jpg", + "target": origin + "/anylink5" + }, + { + "name": "My content 4", + "piece": "My content 4", + "target": "http://img4.example.com" + }, + { + "name": toAbsolutePath("img3-en.jpg"), + "piece": toAbsoluteUrl("img3-en.jpg"), + "target": "http://img3.example.com" + }, + { + "name": "img.jpg", + "piece": "img.jpg", + "target": "http://img2.example.com" + }, + { + "name": toAbsolutePath("img1-en.jpg"), + "piece": toAbsoluteUrl("img1-en.jpg"), + "target": "" + }, + { + "name": "/tests/javascript/img1-en.jpg", + "piece": toAbsoluteUrl("img1-en.jpg"), + "target": "" + }]; + + var consoleOld = console; + var loggedContentBlocks = []; + console = {log: function (content){ + loggedContentBlocks = content; + }}; + tracker.logAllContentBlocksOnPage(); + console = consoleOld; + expected = + [ + { + "name": "My Ad 7", + "piece": "Unknown", + "target": "http://img7.example.com" + }, + { + "name": "http://www.example.com/path/xyz.jpg", + "piece": "http://www.example.com/path/xyz.jpg", + "target": "http://img6.example.com" + }, + { + "name": "My Ad 5", + "piece": "http://img5.example.com/path/xyz.jpg", + "target": origin + "/anylink5" + }, + { + "name": "My content 4", + "piece": "My content 4", + "target": "http://img4.example.com" + }, + { + "name": toAbsolutePath("img3-en.jpg"), + "piece": toAbsoluteUrl("img3-en.jpg"), + "target": "http://img3.example.com" + }, + { + "name": "img.jpg", + "piece": "img.jpg", + "target": "http://img2.example.com" + }, + { + "name": toAbsolutePath("img1-en.jpg"), + "piece": toAbsoluteUrl("img1-en.jpg"), + "target": "" + }, + { + "name": "/tests/javascript/img1-en.jpg", + "piece": toAbsoluteUrl("img1-en.jpg"), + "target": "" + }]; + + equal(expected.length, loggedContentBlocks.length, 'logAllContentBlocksOnPage should detect correct number of content blocks'); + equal(JSON.stringify(expected), JSON.stringify(loggedContentBlocks), 'logAllContentBlocksOnPage should log all content blocks'); }); test("trackingContentInteractionInteractive", function() { |