<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[12982] sites/trunk/wordpress.org/public_html/wp-content/plugins/tour: Tour: update from upstream</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/12982">12982</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/12982","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>akirk</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2023-11-29 13:15:56 +0000 (Wed, 29 Nov 2023)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Tour: update from upstream</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourREADMEmd">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/README.md</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetscssstylecss">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/css/style.css</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsjstourjs">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourtourphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/tour.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/</li>
<li>sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/</li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildblockjson">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/block.json</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildindexassetphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.asset.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildindexcss">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.css</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildindexjs">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildstyleindexcss">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/style-index.css</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildviewassetphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.asset.php</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildviewjs">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsjstourstepeditorjs">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-step-editor.js</a></li>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourclasstourphp">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/class-tour.php</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsjstouradminjs">sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-admin.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourREADMEmd"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/README.md</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/README.md 2023-11-28 20:53:04 UTC (rev 12981)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/README.md 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -24,6 +24,25 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> ## Screenshots
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+## Demo Videos
+
+### Going through a Tour
+
+
+
+https://github.com/Automattic/tour/assets/203408/783bb967-2907-45b8-8bd9-da7f32147ea0
+
+
+
+### Creating a Tour
+
+
+
+
+https://github.com/Automattic/tour/assets/203408/be7f56d6-3869-4afb-9393-242312306180
+
+
</ins><span class="cx" style="display: block; padding: 0 10px"> ## Changelog
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> ### 1.0.0
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildblockjson"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/block.json</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/block.json (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/block.json 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,29 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+{
+ "$schema": "https://schemas.wp.org/trunk/block.json",
+ "apiVersion": 3,
+ "name": "tour/available-tours",
+ "version": "0.1.0",
+ "title": "Available Tours",
+ "category": "widgets",
+ "icon": "testimonial",
+ "description": "Show a list of available tours.",
+ "attributes": {
+ "noToursText": {
+ "type": "string",
+ "default": "There are no tours available."
+ }
+ },
+ "example": {
+ "attributes": {
+ "noToursText": "Here a list of the available tours would be shown."
+ }
+ },
+ "supports": {
+ "html": false
+ },
+ "textdomain": "tour",
+ "editorScript": "file:./index.js",
+ "editorStyle": "file:./index.css",
+ "style": "file:./style-index.css",
+ "viewScript": "file:./view.js"
+}
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildindexassetphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.asset.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.asset.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.asset.php 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-i18n', 'wp-server-side-render'), 'version' => 'ff020029dbdcac61b39f');
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.asset.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildindexcss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.css (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.css 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.css
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildindexjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.js (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/index.js 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+(()=>{"use strict";var e,r={389:(e,r,t)=>{const o=window.wp.blocks,n=window.React,a=window.wp.i18n,l=window.wp.blockEditor,i=window.wp.serverSideRender;var s=t.n(i);const u=window.wp.components,c=JSON.parse('{"u2":"tour/available-tours"}');(0,o.registerBlockType)(c.u2,{edit:function({attributes:e,setAttributes:r}){return(0,n.createElement)("div",{...(0,l.useBlockProps)()},(0,n.createElement)(l.InspectorControls,{key:"settings"},(0,n.createElement)(u.PanelBody,null,(0,n.createElement)(u.TextControl,{label:(0,a.__)("No Tours Text","tour"),value:e.noToursText,onChange:e=>r({noToursText:e})}))),(0,n.createElement)(s(),{block:"tour/available-tours",attributes:e}))}})}},t={};function o(e){var n=t[e];if(void 0!==n)return n.exports;var a=t[e]={exports:{}};return r[e](a,a.exports,o),a.exports}o.m=r,e=[],o.O=(
r,t,n,a)=>{if(!t){var l=1/0;for(c=0;c<e.length;c++){for(var[t,n,a]=e[c],i=!0,s=0;s<t.length;s++)(!1&a||l>=a)&&Object.keys(o.O).every((e=>o.O[e](t[s])))?t.splice(s--,1):(i=!1,a<l&&(l=a));if(i){e.splice(c--,1);var u=n();void 0!==u&&(r=u)}}return r}a=a||0;for(var c=e.length;c>0&&e[c-1][2]>a;c--)e[c]=e[c-1];e[c]=[t,n,a]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),(()=>{var e={826:0,431:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var n,a,[l,i,s]=t,u=0;if(l.some((r=>0!==e[r]))){for(n in i)o.o(i,n)&&(o.m[n]=i[n]);if(s)var c=s(o)}for(r&&r(t);u<l.length;u++)a=l[u],o.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return o.O(c)},t=globalThis.webpackChunktour=globalThis.webpackChunktour||[];t.fo
rEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var n=o.O(void 0,[431],(()=>o(389)));n=o.O(n)})();
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildstyleindexcss"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/style-index.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/style-index.css (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/style-index.css 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/style-index.css
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildviewassetphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.asset.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.asset.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.asset.php 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php return array('dependencies' => array(), 'version' => '31d6cfe0d16ae931b73c');
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.asset.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsblocksbuildviewjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/blocks/build/view.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/css/style.css
===================================================================
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/css/style.css 2023-11-28 20:53:04 UTC (rev 12981)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/css/style.css 2023-11-29 13:15:56 UTC (rev 12982)
</ins><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,10 +1,45 @@
</span><span class="cx" style="display: block; padding: 0 10px"> .pulse {
</span><span class="cx" style="display: block; padding: 0 10px"> border-radius: 50%;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- position: relative;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ position: absolute;
</ins><span class="cx" style="display: block; padding: 0 10px"> cursor: pointer;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- top: 0em;
- left: -0.4em;
</del><span class="cx" style="display: block; padding: 0 10px"> width: 12px;
</span><span class="cx" style="display: block; padding: 0 10px"> height: 12px;
</span><span class="cx" style="display: block; padding: 0 10px"> margin: -6px;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+#tour-launcher {
+ position: fixed;
+ bottom: 76px;
+ right: 24px;
+ font-size: 13px;
+ border: 1px solid #ccc;
+ border-radius: 10px;
+ background: #fff;
+ padding: .5em;
+ line-height: 1;
+ box-shadow: 0 0 3px #999;
+ z-index: 999999;
+}
+#tour-launcher span#tour-title {
+ cursor: pointer;
+ line-height: 1.3em;
+}
+#tour-launcher span#tour-title:hover {
+ text-shadow: 0 0 1px #999;
+}
+ul#page-tour-list li {
+ list-style-type: none;
+}
+ul#page-tour-list li a {
+ text-decoration: none;
+ width: 100%;
+ display: block;
+}
+#page-tour-list {
+ font-size: .8em;
+}
+#wp-admin-bar-tour-list {
+ display: none;
+}
+.inline-tour-list {
+ cursor: pointer;
+}
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsjstouradminjs"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-admin.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-admin.js 2023-11-28 20:53:04 UTC (rev 12981)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-admin.js 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,208 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-if ( typeof wp_tour !== 'undefined' ) {
- window.tour = wp_tour;
-}
-var tourSelectorActive = false;
-var tourId;
-var dialogOpen = false;
-
-var setTourCookie = function( tourId ) {
- document.cookie = 'tour=' + escape( tourId ) + ';path=/';
- enableTourCreation();
-}
-
-var deleteTourCookie = function() {
- document.cookie = 'tour=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
- enableTourCreation();
-}
-
-document.addEventListener('click', function( event ) {
- if ( ! event.target.dataset.addMoreStepsText || ! event.target.dataset.tourId ) {
- return;
- }
-
- event.preventDefault();
- if ( event.target.textContent === event.target.dataset.finishTourCreationText ) {
- event.target.textContent = event.target.dataset.addMoreStepsText;
- deleteTourCookie();
- return;
- }
- setTourCookie( event.target.dataset.tourId );
- event.target.textContent = event.target.dataset.finishTourCreationText;
-} );
-
-function enableTourCreation() {
- tourId = document.cookie.indexOf('tour=') > -1 ? unescape(document.cookie.split('tour=')[1].split(';')[0]) : '';
- if ( tourId && document.getElementById('tour-launcher') ) {
- if ( typeof tour_plugin !== 'undefined' && typeof tour_plugin.tours[ tourId ] !== 'undefined' ) {
- document.getElementById('tour-launcher').style.display = 'block';
- document.getElementById('tour-title').textContent = tour_plugin.tours[ tourId ][0].title;
- document.getElementById('tour-steps').textContent = (tour_plugin.tours[ tourId ].length - 1) + ' step' + (tour_plugin.tours[ tourId ].length > 2 ? 's' : '');
- for ( var i = 1; i < tour_plugin.tours[ tourId ].length; i++ ) {
- el = document.querySelector(tour_plugin.tours[ tourId ][i].selector);
- if ( el ) {
- el.style.outline = '1px dashed ' + tour_plugin.tours[ tourId ][0].color;
- } else {
- reportMissingSelector( tour_plugin.tours[ tourId ][0].title, i, tour_plugin.tours[ tourId ][i].selector );
- }
- }
- }
- } else if ( document.getElementById('tour-launcher') ) {
- document.getElementById('tour-launcher').style.display = 'none';
- }
-}
-enableTourCreation();
-
-function reportMissingSelector( tourTitle, step, selector ) {
- var xhr = new XMLHttpRequest();
- xhr.open('POST', tour_plugin.rest_url + 'tour/v1/report-missing');
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
- xhr.send(JSON.stringify({
- tour: tourId,
- selector: selector,
- step: step,
- url: location.href,
- }));
-}
-
-function toggleTourSelector( event ) {
- event.stopPropagation();
- if ( event.target.tagName.toLowerCase() === 'a' ) {
- deleteTourCookie();
- return false;
- }
-
- tourSelectorActive = ! tourSelectorActive;
-
- document.getElementById('tour-launcher').style.color = tourSelectorActive ? tour_plugin.tours[ tourId ][0].color : '';
- return false;
-}
-
-document.getElementById('tour-launcher').addEventListener('click', toggleTourSelector);
-var clearHighlight = function( event ) {
- if ( typeof tour_plugin.tours[ tourId ] !== 'undefined' ) {
- for ( var i = 1; i < tour_plugin.tours[ tourId ].length; i++ ) {
- if ( event.target.matches(tour_plugin.tours[ tourId ][i].selector) ) {
- document.querySelector(tour_plugin.tours[ tourId ][i].selector).style.outline = '1px dashed ' + tour_plugin.tours[ tourId ][0].color;
- return;
- }
- }
- }
- event.target.style.outline = '';
- event.target.style.cursor = '';
-}
-
-var tourStepHighlighter = function(event) {
- var target = event.target;
- if ( ! tourSelectorActive || target.closest('#tour-launcher') ) {
- clearHighlight( event );
- return;
- }
- // Highlight the element on hover
- target.style.outline = '2px solid ' + tour_plugin.tours[ tourId ][0].color;
- target.style.cursor = 'pointer';
-};
-
-var filter_selectors = function( c ) {
- return c.indexOf( 'wp-' ) > -1
- || c.indexOf( 'page' ) > -1
- || c.indexOf( 'post' ) > -1
- || c.indexOf( 'column' ) > -1;
-}
-
-var tourStepSelector = function(event) {
- if ( ! tourSelectorActive ) {
- return;
- }
-
- function getSelectors(elem) {
- var selectors = [];
-
- while ( elem.parentElement ) {
- var currentElement = elem.parentElement;
- var tagName = elem.tagName.toLowerCase();
- var classes = [];
-
- if ( elem.id ) {
- selectors.push( tagName + '#' + elem.id );
- break;
- }
-
- elem.classList.forEach( function( c ) {
- if ( ! filter_selectors( c ) ) {
- return;
- }
- classes.push( c );
- })
-
- if ( classes.length ) {
- selectors.push( tagName + '.' + classes.join( '.') );
- } else {
- var index = Array.prototype.indexOf.call(currentElement.children, elem) + 1;
- selectors.push(tagName + ':nth-child(' + index + ')');
- }
-
- elem = currentElement;
- }
-
- return selectors.reverse();
- }
-
-
- event.preventDefault();
-
- var selectors = getSelectors(event.target);
-
- dialogOpen = true;
- var stepName = prompt( 'Enter description for step ' + tour_plugin.tours[ tourId ].length );
- if ( ! stepName ) {
- event.target.style.outline = '';
- return false;
- }
-
- tour_plugin.tours[ tourId ].push({
- element: selectors.join(' '),
- popover: {
- title: tour_plugin.tours[ tourId ][0].title,
- description: stepName,
- },
- });
-
- event.target.style.outline = '1px dashed ' + tour_plugin.tours[ tourId ][0].color;
-
- if ( tour_plugin.tours[ tourId ].length > 1 ) {
- var xhr = new XMLHttpRequest();
- xhr.open('POST', tour_plugin.rest_url + 'tour/v1/save');
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
- xhr.send(JSON.stringify({
- tour: tourId,
- steps: JSON.stringify(tour_plugin.tours[ tourId ]),
- }));
-
- document.getElementById('tour-steps').textContent = (tour_plugin.tours[ tourId ].length - 1) + ' step' + (tour_plugin.tours[ tourId ].length > 2 ? 's' : '');
- document.getElementById('tour-title').textContent = 'Saved!';
-
- window.loadTour();
- setTimeout(function() {
- document.getElementById('tour-title').textContent = tour_plugin.tours[ tourId ][0].title;
- }, 1000);
- return false;
- }
-
- return false;
-};
-
-document.addEventListener('keyup', function(event) {
- if ( event.keyCode === 27 ) {
- if ( dialogOpen ) {
- dialogOpen = false;
- return;
- }
- tourSelectorActive = false;
- document.getElementById('tour-launcher').style.color = '';
- }
-});
-document.addEventListener('mouseover', tourStepHighlighter);
-document.addEventListener('mouseout', clearHighlight);
-document.addEventListener('click', tourStepSelector);
</del></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsjstourstepeditorjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-step-editor.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-step-editor.js (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour-step-editor.js 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,262 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* global tour_plugin, XMLHttpRequest */
+/* eslint camelcase: "off" */
+
+let tourSelectorActive = false;
+let tourId;
+let dialogOpen = false;
+
+const setTourCookie = function ( id ) {
+ document.cookie = 'tour=' + escape( id ) + ';path=/';
+ enableTourCreation();
+};
+
+const deleteTourCookie = function () {
+ document.cookie = 'tour=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT;';
+ enableTourCreation();
+};
+
+document.addEventListener( 'click', function ( event ) {
+ if (
+ ! event.target.dataset.addMoreStepsText ||
+ ! event.target.dataset.tourId
+ ) {
+ return;
+ }
+
+ event.preventDefault();
+ if (
+ event.target.textContent === event.target.dataset.finishTourCreationText
+ ) {
+ event.target.textContent = event.target.dataset.addMoreStepsText;
+ deleteTourCookie();
+ return;
+ }
+ setTourCookie( event.target.dataset.tourId );
+ event.target.textContent = event.target.dataset.finishTourCreationText;
+} );
+
+function enableTourCreation() {
+ tourId =
+ document.cookie.indexOf( 'tour=' ) > -1
+ ? unescape(
+ document.cookie.split( 'tour=' )[ 1 ].split( ';' )[ 0 ]
+ )
+ : '';
+ if ( tourId && document.getElementById( 'tour-launcher' ) ) {
+ if (
+ typeof tour_plugin !== 'undefined' &&
+ typeof tour_plugin.tours[ tourId ] !== 'undefined'
+ ) {
+ document.getElementById( 'tour-launcher' ).style.display = 'block';
+ document.getElementById( 'tour-title' ).textContent =
+ tour_plugin.tours[ tourId ][ 0 ].title;
+ document.getElementById( 'tour-steps' ).textContent =
+ tour_plugin.tours[ tourId ].length -
+ 1 +
+ ' step' +
+ ( tour_plugin.tours[ tourId ].length > 2 ? 's' : '' );
+ for ( let i = 1; i < tour_plugin.tours[ tourId ].length; i++ ) {
+ const el = document.querySelector(
+ tour_plugin.tours[ tourId ][ i ].selector
+ );
+ if ( el ) {
+ el.style.outline =
+ '1px dashed ' + tour_plugin.tours[ tourId ][ 0 ].color;
+ } else {
+ reportMissingSelector(
+ tour_plugin.tours[ tourId ][ 0 ].title,
+ i,
+ tour_plugin.tours[ tourId ][ i ].selector
+ );
+ }
+ }
+ }
+ } else if ( document.getElementById( 'tour-launcher' ) ) {
+ document.getElementById( 'tour-launcher' ).style.display = 'none';
+ }
+}
+enableTourCreation();
+
+function reportMissingSelector( tourTitle, step, selector ) {
+ const xhr = new XMLHttpRequest();
+ xhr.open( 'POST', tour_plugin.rest_url + 'tour/v1/report-missing' );
+ xhr.setRequestHeader( 'Content-Type', 'application/json' );
+ xhr.setRequestHeader( 'X-WP-Nonce', tour_plugin.nonce );
+ xhr.send(
+ JSON.stringify( {
+ tour: tourId,
+ selector,
+ step,
+ url: window.location.href,
+ } )
+ );
+}
+
+function toggleTourSelector( event ) {
+ event.stopPropagation();
+ if ( event.target.tagName.toLowerCase() === 'a' ) {
+ deleteTourCookie();
+ return false;
+ }
+
+ tourSelectorActive = ! tourSelectorActive;
+
+ document.getElementById( 'tour-launcher' ).style.color = tourSelectorActive
+ ? tour_plugin.tours[ tourId ][ 0 ].color
+ : '';
+ return false;
+}
+
+document
+ .getElementById( 'tour-launcher' )
+ .addEventListener( 'click', toggleTourSelector );
+const clearHighlight = function ( event ) {
+ if ( typeof tour_plugin.tours[ tourId ] !== 'undefined' ) {
+ for ( let i = 1; i < tour_plugin.tours[ tourId ].length; i++ ) {
+ if (
+ event.target.matches(
+ tour_plugin.tours[ tourId ][ i ].selector
+ )
+ ) {
+ document.querySelector(
+ tour_plugin.tours[ tourId ][ i ].selector
+ ).style.outline =
+ '1px dashed ' + tour_plugin.tours[ tourId ][ 0 ].color;
+ return;
+ }
+ }
+ }
+ event.target.style.outline = '';
+ event.target.style.cursor = '';
+};
+
+const tourStepHighlighter = function ( event ) {
+ const target = event.target;
+ if ( ! tourSelectorActive || target.closest( '#tour-launcher' ) ) {
+ clearHighlight( event );
+ return;
+ }
+ // Highlight the element on hover
+ target.style.outline =
+ '2px solid ' + tour_plugin.tours[ tourId ][ 0 ].color;
+ target.style.cursor = 'pointer';
+};
+
+const filter_selectors = function ( c ) {
+ return (
+ c.indexOf( 'wp-' ) > -1 ||
+ c.indexOf( 'page' ) > -1 ||
+ c.indexOf( 'post' ) > -1 ||
+ c.indexOf( 'column' ) > -1
+ );
+};
+
+const tourStepSelector = function ( event ) {
+ if ( ! tourSelectorActive ) {
+ return;
+ }
+
+ function getSelectors( elem ) {
+ const selectors = [];
+
+ while ( elem.parentElement ) {
+ const currentElement = elem.parentElement;
+ const tagName = elem.tagName.toLowerCase();
+ const classes = [];
+
+ if ( elem.id ) {
+ selectors.push( tagName + '#' + elem.id );
+ break;
+ }
+
+ elem.classList.forEach( function ( c ) {
+ if ( ! filter_selectors( c ) ) {
+ return;
+ }
+ classes.push( c );
+ } );
+
+ if ( classes.length ) {
+ selectors.push( tagName + '.' + classes.join( '.' ) );
+ } else {
+ const index =
+ Array.prototype.indexOf.call(
+ currentElement.children,
+ elem
+ ) + 1;
+ selectors.push( tagName + ':nth-child(' + index + ')' );
+ }
+
+ elem = currentElement;
+ }
+
+ return selectors.reverse();
+ }
+
+ event.preventDefault();
+
+ dialogOpen = true;
+
+ const stepName = /* eslint-disable-line no-alert */ window.prompt(
+ 'Enter description for step ' + tour_plugin.tours[ tourId ].length
+ );
+
+ if ( ! stepName ) {
+ event.target.style.outline = '';
+ return false;
+ }
+
+ const selectors = getSelectors( event.target );
+ tour_plugin.tours[ tourId ].push( {
+ element: selectors.join( ' ' ),
+ popover: {
+ title: tour_plugin.tours[ tourId ][ 0 ].title,
+ description: stepName,
+ },
+ } );
+
+ event.target.style.outline =
+ '1px dashed ' + tour_plugin.tours[ tourId ][ 0 ].color;
+
+ if ( tour_plugin.tours[ tourId ].length > 1 ) {
+ const xhr = new XMLHttpRequest();
+ xhr.open( 'POST', tour_plugin.rest_url + 'tour/v1/save' );
+ xhr.setRequestHeader( 'Content-Type', 'application/json' );
+ xhr.setRequestHeader( 'X-WP-Nonce', tour_plugin.nonce );
+ xhr.send(
+ JSON.stringify( {
+ tour: tourId,
+ steps: JSON.stringify( tour_plugin.tours[ tourId ] ),
+ } )
+ );
+
+ document.getElementById( 'tour-steps' ).textContent =
+ tour_plugin.tours[ tourId ].length -
+ 1 +
+ ' step' +
+ ( tour_plugin.tours[ tourId ].length > 2 ? 's' : '' );
+ document.getElementById( 'tour-title' ).textContent = 'Saved!';
+
+ setTimeout( function () {
+ document.getElementById( 'tour-title' ).textContent =
+ tour_plugin.tours[ tourId ][ 0 ].title;
+ }, 1000 );
+ return false;
+ }
+
+ return false;
+};
+
+document.addEventListener( 'keyup', function ( event ) {
+ if ( event.keyCode === 27 ) {
+ if ( dialogOpen ) {
+ dialogOpen = false;
+ return;
+ }
+ tourSelectorActive = false;
+ document.getElementById( 'tour-launcher' ).style.color = '';
+ }
+} );
+document.addEventListener( 'mouseover', tourStepHighlighter );
+document.addEventListener( 'mouseout', clearHighlight );
+document.addEventListener( 'click', tourStepSelector );
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourassetsjstourjs"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour.js 2023-11-28 20:53:04 UTC (rev 12981)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/assets/js/tour.js 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,9 +1,9 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-/* global , document, window, wp_tour */
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/* global tour_plugin, XMLHttpRequest */
</ins><span class="cx" style="display: block; padding: 0 10px"> /* eslint camelcase: "off" */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-document.addEventListener('DOMContentLoaded', function() {
- var dismissTour;
- document.addEventListener('click', function( event ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+document.addEventListener( 'DOMContentLoaded', function () {
+ let dismissTour;
+ document.addEventListener( 'click', function ( event ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( ! event.target.matches( '.pulse' ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -10,7 +10,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> event.preventDefault();
</span><span class="cx" style="display: block; padding: 0 10px"> const driver = window.driver.js.driver;
</span><span class="cx" style="display: block; padding: 0 10px"> const tourId = event.target.dataset.tourId;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- var startStep = 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ let startStep = 0;
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( typeof tour_plugin.progress[ tourId ] !== 'undefined' ) {
</span><span class="cx" style="display: block; padding: 0 10px"> startStep = tour_plugin.progress[ tourId ] - 1;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -17,62 +17,77 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ( startStep <= 0 ) {
</span><span class="cx" style="display: block; padding: 0 10px"> startStep = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- var tourSteps = tour_plugin.tours[ tourId ].slice(1);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const tourSteps = tour_plugin.tours[ tourId ].slice( 1 );
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( ! tourSteps.length ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- dismissTour = function() {
- var xhr = new XMLHttpRequest();
- xhr.open('POST', tour_plugin.rest_url + 'tour/v1/save-progress');
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
- xhr.send(JSON.stringify({
- tour: tourId,
- step: tour_plugin.tours[ tourId ].length
- }));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ dismissTour = function () {
+ const xhr = new XMLHttpRequest();
+ xhr.open( 'POST', tour_plugin.rest_url + 'tour/v1/save-progress' );
+ xhr.setRequestHeader( 'Content-Type', 'application/json' );
+ xhr.setRequestHeader( 'X-WP-Nonce', tour_plugin.nonce );
+ xhr.send(
+ JSON.stringify( {
+ tour: tourId,
+ step: tour_plugin.tours[ tourId ].length,
+ } )
+ );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> driverObj.destroy();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- }
- tourSteps[startStep].element = event.target.closest('.pulse-wrapper');
- var driverObj = driver( {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ };
+ tourSteps[ startStep ].element =
+ event.target.closest( '.pulse-wrapper' );
+ const driverObj = driver( {
</ins><span class="cx" style="display: block; padding: 0 10px"> showProgress: true,
</span><span class="cx" style="display: block; padding: 0 10px"> steps: tourSteps,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- onHighlightStarted: function( element, step, options ) {
- step.popover.description += '<br><a href="" class="dismiss-tour">Dismiss the tour';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ onHighlightStarted( element, step ) {
+ step.popover.description +=
+ '<br><a href="" class="dismiss-tour">Dismiss the tour';
</ins><span class="cx" style="display: block; padding: 0 10px"> },
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- onHighlighted: function( element, step, options ) {
- var xhr = new XMLHttpRequest();
- xhr.open('POST', tour_plugin.rest_url + 'tour/v1/save-progress');
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
- xhr.send(JSON.stringify({
- tour: tourId,
- step: options.state.activeIndex + 1
- }));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ onHighlighted( element, step, options ) {
+ tour_plugin.progress[ tourId ] = options.state.activeIndex + 1;
+ const xhr = new XMLHttpRequest();
+ xhr.open(
+ 'POST',
+ tour_plugin.rest_url + 'tour/v1/save-progress'
+ );
+ xhr.setRequestHeader( 'Content-Type', 'application/json' );
+ xhr.setRequestHeader( 'X-WP-Nonce', tour_plugin.nonce );
+ xhr.send(
+ JSON.stringify( {
+ tour: tourId,
+ step: options.state.activeIndex + 1,
+ } )
+ );
</ins><span class="cx" style="display: block; padding: 0 10px"> },
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- onDestroyStarted: function( element, step, options ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ onDestroyStarted( element, step, options ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( driverObj.hasNextStep() ) {
</span><span class="cx" style="display: block; padding: 0 10px"> addPulse( tourId, options.state.activeIndex + 1 );
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- var xhr = new XMLHttpRequest();
- xhr.open('POST', tour_plugin.rest_url + 'tour/v1/save-progress');
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
- xhr.send(JSON.stringify({
- tour: tourId,
- step: tour_plugin.tours[ tourId ].length
- }));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const xhr = new XMLHttpRequest();
+ xhr.open(
+ 'POST',
+ tour_plugin.rest_url + 'tour/v1/save-progress'
+ );
+ xhr.setRequestHeader( 'Content-Type', 'application/json' );
+ xhr.setRequestHeader( 'X-WP-Nonce', tour_plugin.nonce );
+ xhr.send(
+ JSON.stringify( {
+ tour: tourId,
+ step: tour_plugin.tours[ tourId ].length,
+ } )
+ );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> driverObj.destroy();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ },
</ins><span class="cx" style="display: block; padding: 0 10px"> } );
</span><span class="cx" style="display: block; padding: 0 10px"> driverObj.drive( startStep );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const pulse = tourSteps[startStep].element.querySelector('.pulse');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const pulse = tourSteps[ startStep ].element.querySelector( '.pulse' );
</ins><span class="cx" style="display: block; padding: 0 10px"> pulse.parentNode.removeChild( pulse );
</span><span class="cx" style="display: block; padding: 0 10px"> } );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- document.addEventListener('click', function( event ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ document.addEventListener( 'click', function ( event ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( ! event.target.matches( '.dismiss-tour' ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> return;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -82,7 +97,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } );
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px"> function addPulse( tourId, startStep ) {
</span><span class="cx" style="display: block; padding: 0 10px"> let fields;
</span><span class="cx" style="display: block; padding: 0 10px"> if ( startStep === 0 ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -102,66 +116,99 @@
</span><span class="cx" style="display: block; padding: 0 10px"> fields = [ selector ];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- for (let i = 0; i < fields.length; i++) {
- let field = fields[i];
- let wrapper = field.closest('.pulse-wrapper');
- if (!wrapper) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ for ( let i = 0; i < fields.length; i++ ) {
+ const field = fields[ i ];
+ let wrapper = field.closest( '.pulse-wrapper' );
+ if ( ! wrapper ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( field.hasChildNodes() ) {
</span><span class="cx" style="display: block; padding: 0 10px"> wrapper = field;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- wrapper = document.createElement('div');
- field.parentNode.insertBefore(wrapper, field);
- wrapper.appendChild(field);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wrapper = document.createElement( 'div' );
+ field.parentNode.insertBefore( wrapper, field );
+ wrapper.appendChild( field );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- wrapper.classList.add("pulse-wrapper");
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wrapper.classList.add( 'pulse-wrapper' );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ( ! wrapper.querySelector('.pulse') ) {
- const pulse = document.createElement('div');
- pulse.classList.add("pulse");
- pulse.classList.add("tour-" + tourId);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! wrapper.querySelector( '.pulse' ) ) {
+ const pulse = document.createElement( 'div' );
+ pulse.classList.add( 'pulse' );
+ pulse.classList.add( 'tour-' + tourId );
</ins><span class="cx" style="display: block; padding: 0 10px"> pulse.dataset.tourId = tourId;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- pulse.dataset.tourId = tourId;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ pulse.dataset.tourTitle =
+ tour_plugin.tours[ tourId ][ 0 ].title;
</ins><span class="cx" style="display: block; padding: 0 10px"> if ( field.hasChildNodes() ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- wrapper.insertBefore(pulse,wrapper.firstChild);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wrapper.insertBefore( pulse, wrapper.firstChild );
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- wrapper.insertBefore(pulse,field);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ wrapper.insertBefore( pulse, field );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const loadTour = function() {
- var color1 = '';
- var color2 = '';
- var styleElement = document.createElement( 'style' );
- var style;
- var startStep;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const loadTour = function () {
+ const styleElement =
+ document.getElementById( 'tour-styles' ) ||
+ document.createElement( 'style' );
+ let style = null;
+ let color1 = '';
+ let color2 = '';
+ let startStep;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- document.head.appendChild( styleElement );
- style = styleElement.sheet;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! styleElement.id ) {
+ styleElement.id = 'tour-styles';
+ document.head.appendChild( styleElement );
+ style = styleElement.sheet;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> for ( const tourId in tour_plugin.tours ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- color1 = tour_plugin.tours[ tourId ][ 0 ].color;
- color2 = tour_plugin.tours[ tourId ][ 0 ].color + 'a0';
- style.insertRule( '@keyframes animation-' + tourId + ' {' +
- '0% {' +
- 'box-shadow: 0 0 0 0 ' + color2 + ';' +
- '}' +
- '70% {' +
- 'box-shadow: 0 0 0 10px ' + color1 + '00' + ';' +
- '}' +
- '100% {' +
- 'box-shadow: 0 0 0 0 ' + color1 + '00' + ';' +
- '}' +
- '}',
- style.cssRules.length );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( style ) {
+ color1 = tour_plugin.tours[ tourId ][ 0 ].color;
+ color2 = tour_plugin.tours[ tourId ][ 0 ].color + 'a0';
+ style.insertRule(
+ '@keyframes animation-' +
+ tourId +
+ ' {' +
+ '0% {' +
+ 'box-shadow: 0 0 0 0 ' +
+ color2 +
+ ';' +
+ '}' +
+ '70% {' +
+ 'box-shadow: 0 0 0 10px ' +
+ color1 +
+ '00' +
+ ';' +
+ '}' +
+ '100% {' +
+ 'box-shadow: 0 0 0 0 ' +
+ color1 +
+ '00' +
+ ';' +
+ '}' +
+ '}',
+ style.cssRules.length
+ );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- style.insertRule( '.tour-' + tourId + '{' +
- 'box-shadow: 0 0 0 ' + color2 + ';' +
- 'background: ' + color1 + '80' + ';' +
- '-webkit-animation: animation-' + tourId + ' 2s infinite;' +
- 'animation: animation-' + tourId + ' 2s infinite; }',
- style.cssRules.length );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ style.insertRule(
+ '.tour-' +
+ tourId +
+ '{' +
+ 'box-shadow: 0 0 0 ' +
+ color2 +
+ ';' +
+ 'background: ' +
+ color1 +
+ '80' +
+ ';' +
+ '-webkit-animation: animation-' +
+ tourId +
+ ' 2s infinite;' +
+ 'animation: animation-' +
+ tourId +
+ ' 2s infinite; }',
+ style.cssRules.length
+ );
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> startStep = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> if ( typeof tour_plugin.progress[ tourId ] !== 'undefined' ) {
</span><span class="cx" style="display: block; padding: 0 10px"> startStep = tour_plugin.progress[ tourId ];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -170,5 +217,100 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> };
</span><span class="cx" style="display: block; padding: 0 10px"> loadTour();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-}
-);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ filter_available_tours();
+ setTimeout( filter_available_tours, 500 );
+
+ function filter_available_tours() {
+ const tourListItems = document.querySelectorAll( '.tour-list-item' );
+ let foundTour = false;
+
+ for ( let i = 0; i < tourListItems.length; i++ ) {
+ let tourId = tourListItems[ i ].dataset.tourId;
+ if (
+ ! tourId &&
+ tourListItems[ i ].id.substr( 0, 18 ) === 'wp-admin-bar-tour-'
+ ) {
+ tourId = tourListItems[ i ].id.substr( 18 );
+ }
+
+ if ( ! tour_plugin.tours[ tourId ] ) {
+ continue;
+ }
+
+ const tourIsPresent =
+ tour_plugin.tours[ tourId ][ 1 ] &&
+ document.querySelector(
+ tour_plugin.tours[ tourId ][ 1 ].element
+ );
+ if ( tourIsPresent ) {
+ foundTour = true;
+ }
+ document
+ .querySelectorAll(
+ '.tour-list-item[data-tour-id="' +
+ tourId +
+ '"], #wp-admin-bar-tour-' +
+ tourId
+ )
+ .forEach( function ( element ) {
+ element.style.display = tourIsPresent ? 'block' : 'none';
+ } );
+ }
+
+ if ( document.getElementById( 'wp-admin-bar-tour-list-default' ) ) {
+ document
+ .getElementById( 'wp-admin-bar-tour-list-default' )
+ .childNodes.forEach( function ( element ) {
+ if ( element.style.display !== 'none' ) {
+ document.getElementById(
+ 'wp-admin-bar-tour-list'
+ ).style.display = 'block';
+ }
+ } );
+ }
+
+ if ( foundTour ) {
+ loadTour();
+ }
+ }
+
+ document.addEventListener( 'click', function ( event ) {
+ let target = event.target;
+ if ( target.matches( '.tour-list-item a' ) ) {
+ target = target.parentNode;
+ } else if ( ! target.matches( '.tour-list-item' ) ) {
+ return true;
+ }
+ event.preventDefault();
+
+ let tourId = target.dataset.tourId;
+ if ( ! tourId && target.id.substr( 0, 18 ) === 'wp-admin-bar-tour-' ) {
+ tourId = target.id.substr( 18 );
+ }
+
+ if ( ! tour_plugin.tours[ tourId ] ) {
+ return false;
+ }
+ let pulseToClick = document.querySelector( '.pulse.tour-' + tourId );
+
+ if ( pulseToClick ) {
+ pulseToClick.click();
+ } else {
+ const xhr = new XMLHttpRequest();
+ xhr.open( 'POST', tour_plugin.rest_url + 'tour/v1/save-progress' );
+ xhr.setRequestHeader( 'Content-Type', 'application/json' );
+ xhr.setRequestHeader( 'X-WP-Nonce', tour_plugin.nonce );
+ xhr.send(
+ JSON.stringify( {
+ tour: tourId,
+ step: -1,
+ } )
+ );
+
+ delete tour_plugin.progress[ tourId ];
+ loadTour();
+ pulseToClick = document.querySelector( '.pulse.tour-' + tourId );
+ pulseToClick.click();
+ }
+ } );
+} );
</ins></span></pre></div>
<a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourclasstourphp"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/class-tour.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/class-tour.php (rev 0)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/class-tour.php 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,803 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * @package Tour
+ */
+
+/**
+ * The class containting all hooks for the Tour.
+ */
+class Tour {
+ /**
+ * Register all hooks.
+ */
+ public static function register_hooks() {
+ $class = get_called_class();
+ add_action( 'admin_enqueue_scripts', array( $class, 'enqueue_scripts' ) );
+ add_action( 'wp_enqueue_scripts', array( $class, 'enqueue_scripts' ) );
+ add_action( 'gp_head', array( $class, 'enqueue_scripts' ) );
+ add_action( 'init', array( $class, 'register_post_type' ) );
+ add_action( 'init', array( $class, 'register_block_type' ) );
+ add_action( 'rest_api_init', array( $class, 'rest_api_init' ) );
+ add_filter( 'post_row_actions', array( $class, 'post_row_actions' ), 10, 2 );
+ add_filter( 'tour_row_actions', array( $class, 'tour_row_actions' ) );
+ add_filter( 'get_the_excerpt', array( $class, 'get_the_excerpt' ), 10, 2 );
+ add_filter( 'wp_insert_post_data', array( $class, 'wp_insert_post_data' ), 10, 2 );
+ add_action( 'postbox_classes_tour_tour-json', array( $class, 'add_closed_css_class' ) );
+ add_action( 'admin_init', array( $class, 'admin_init' ) );
+ add_action( 'edit_form_after_editor', array( $class, 'edit_form_after_editor' ) );
+ add_filter( 'tour_list', array( $class, 'tour_list' ) );
+ add_shortcode( 'tour_button', array( $class, 'show_tour_list' ) );
+ add_action( 'admin_menu', array( $class, 'add_admin_menu' ) );
+ add_action( 'wp_footer', array( $class, 'output_tour_button' ) );
+ add_action( 'admin_footer', array( $class, 'output_tour_button' ) );
+ add_action( 'show_user_profile', array( $class, 'show_user_profile' ) );
+ add_action( 'wp_before_admin_bar_render', array( $class, 'add_tours_menu_to_masterbar' ) );
+ }
+
+ /**
+ * Enqueue the scripts.
+ */
+ public static function enqueue_scripts() {
+ static $once = false;
+ if ( $once ) {
+ return;
+ }
+ $once = true;
+
+ $tours = apply_filters( 'tour_list', array() );
+ if ( empty( $tours ) ) {
+ return;
+ }
+
+ wp_register_style( 'driver-js', plugins_url( 'assets/css/driver-js.css', __FILE__ ), array(), filemtime( __DIR__ . '/assets/css/driver-js.css' ) );
+ wp_register_style( 'tour-css', plugins_url( 'assets/css/style.css', __FILE__ ), array(), filemtime( __DIR__ . '/assets/css/style.css' ) );
+ wp_enqueue_style( 'driver-js' );
+ wp_enqueue_style( 'tour-css' );
+ wp_enqueue_script( 'driver-js', plugins_url( 'assets/js/driver-js.js', __FILE__ ), array(), filemtime( __DIR__ . '/assets/js/driver-js.js' ), array( 'in_footer' => true ) );
+ wp_register_script( 'tour', plugins_url( 'assets/js/tour.js', __FILE__ ), array( 'driver-js' ), filemtime( __DIR__ . '/assets/js/tour.js' ), false );
+ wp_enqueue_script( 'tour' );
+ wp_localize_script(
+ 'tour',
+ 'tour_plugin',
+ array(
+ 'tours' => $tours,
+ 'nonce' => wp_create_nonce( 'wp_rest' ),
+ 'rest_url' => rest_url(),
+ 'progress' => get_user_option( 'tour-progress', get_current_user_id() ),
+ )
+ );
+
+ if ( current_user_can( 'edit_posts' ) ) {
+ wp_register_script( 'tour-step-editor', plugins_url( 'assets/js/tour-step-editor.js', __FILE__ ), array( 'driver-js' ), filemtime( __DIR__ . '/assets/js/tour-step-editor.js' ), array( 'in_footer' => true ) );
+ wp_enqueue_script( 'tour-step-editor' );
+ }
+ }
+
+ /**
+ * Ensure that the post_content is properly decoded to JSON.
+ *
+ * @param string $post_content The post content.
+ *
+ * @return array The decoded JSON.
+ */
+ private static function json_decode( $post_content ) {
+ return json_decode( wp_unslash( str_replace( "\\\\'", "'", $post_content ) ), true );
+ }
+
+ /**
+ * Register the post type.
+ */
+ public static function register_post_type() {
+ register_post_type(
+ 'tour',
+ array(
+ 'labels' => array(
+ 'name' => __( 'Tours', 'tour' ),
+ 'singular_name' => __( 'Tour', 'tour' ),
+ 'add_new' => __( 'Create New', 'tour' ),
+ 'add_new_item' => __( 'Create New Tour', 'tour' ),
+ 'edit_item' => __( 'Edit Tour', 'tour' ),
+ 'new_item' => __( 'New Tour', 'tour' ),
+ 'all_items' => __( 'All Tours', 'tour' ),
+ 'view_item' => __( 'View Tour', 'tour' ),
+ 'search_items' => __( 'Search Tours', 'tour' ),
+ 'not_found' => __( 'No tours found.', 'tour' ),
+
+ ),
+
+ 'public' => false,
+ 'show_ui' => true,
+ 'show_in_nav_menus' => true,
+ 'show_in_menu' => 'tour',
+ 'supports' => array( 'title', 'revisions' ),
+ )
+ );
+ }
+
+ /**
+ * Initialize the REST API endpoints.
+ */
+ public static function rest_api_init() {
+ register_rest_route(
+ 'tour/v1',
+ 'save-progress',
+ array(
+ 'methods' => 'POST',
+ 'callback' => function ( WP_REST_Request $request ) {
+ if ( ! is_user_logged_in() ) {
+ return array( 'success' => 'logged-out' );
+ }
+ $step = $request->get_param( 'step' );
+ $tour_id = $request->get_param( 'tour' );
+
+ $tour = get_post( $tour_id );
+ if ( ! $tour || is_wp_error( $tour ) || 'tour' !== $tour->post_type ) {
+ return array(
+ 'success' => false,
+ );
+ }
+
+ $tour_progress = get_user_option( 'tour-progress', get_current_user_id() );
+ if ( ! $tour_progress ) {
+ $tour_progress = array();
+ }
+ if ( $step < 0 || ! is_numeric( $step ) ) {
+ unset( $tour_progress[ $tour_id ] );
+ } else {
+ $tour_progress[ $tour_id ] = $step;
+ }
+ update_user_option( get_current_user_id(), 'tour-progress', $tour_progress );
+ return array(
+ 'success' => true,
+ );
+ },
+ )
+ );
+
+ register_rest_route(
+ 'tour/v1',
+ 'report-missing',
+ array(
+ 'methods' => 'POST',
+ 'callback' => function ( WP_REST_Request $request ) {
+ $step = $request->get_param( 'step' );
+ $tour_id = $request->get_param( 'tour' );
+ $selector = $request->get_param( 'selector' );
+ $url = $request->get_param( 'url' );
+
+ $tour = get_post( $tour_id );
+ if ( ! $tour || is_wp_error( $tour ) || 'tour' !== $tour->post_type ) {
+ return array(
+ 'success' => false,
+ );
+ }
+
+ if ( $tour ) {
+ $missing_steps = get_post_meta( $tour, 'missing_steps', true );
+ if ( ! $missing_steps ) {
+ $missing_steps = array();
+ }
+ if ( ! isset( $missing_steps[ $step ] ) ) {
+ $missing_steps[ $step ] = array();
+ }
+ if ( ! isset( $missing_steps[ $step ][ $url ] ) ) {
+ $missing_steps[ $step ][ $url ] = array();
+ }
+ if ( ! isset( $missing_steps[ $step ][ $url ][ $selector ] ) ) {
+ $missing_steps[ $step ][ $url ][ $selector ] = 0;
+ }
+ $missing_steps[ $step ][ $url ][ $selector ] += 1;
+ update_post_meta( $tour, 'missing_steps', $missing_steps );
+ return array(
+ 'success' => true,
+ );
+ }
+ return array(
+ 'success' => false,
+ );
+ },
+ )
+ );
+
+ register_rest_route(
+ 'tour/v1',
+ 'save',
+ array(
+ 'methods' => 'POST',
+ 'callback' => function ( WP_REST_Request $request ) {
+ if ( ! current_user_can( 'edit_posts' ) ) {
+ return array(
+ 'success' => false,
+ );
+ }
+ $steps = json_decode( $request->get_param( 'steps' ), true );
+ if ( ! isset( $steps[0]['title'] ) ) {
+ return array(
+ 'success' => false,
+ );
+ }
+ if ( ! isset( $steps[1]['popover'] ) ) {
+ return array(
+ 'success' => false,
+ );
+ }
+ $tour_id = $request->get_param( 'tour' );
+
+ $tour = get_post( $tour_id );
+ if ( ! $tour || is_wp_error( $tour ) || 'tour' !== $tour->post_type ) {
+ return array(
+ 'success' => false,
+ );
+ }
+
+ if ( $tour ) {
+ wp_update_post(
+ array(
+ 'ID' => $tour_id,
+ 'post_content' => wp_json_encode( $steps, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ),
+ 'post_status' => 'publish',
+ ),
+ true
+ );
+ }
+
+ return $tour_id;
+ },
+ )
+ );
+ }
+
+ /**
+ * Register post row actions.
+ *
+ * @param array $actions The actions.
+ * @param WP_Post $post The post.
+ *
+ * @return array The modified actions.
+ */
+ public static function post_row_actions( $actions, $post ) {
+ if ( 'tour' !== $post->post_type || 'trash' === $post->post_status ) {
+ return $actions;
+ }
+
+ $tour_steps = self::json_decode( $post->post_content );
+ if ( empty( $tour_steps[0]['title'] ) ) {
+ return $actions;
+ }
+
+ $caption = __( 'Add more steps', 'tour' );
+
+ $actions['add-more-steps'] = '<a href="' . get_permalink( $post->ID ) . '" data-tour-id="' . esc_attr( $post->ID ) . '" data-add-more-steps-text="' . esc_attr( $caption ) . '" data-finish-tour-creation-text="' . esc_attr( __( 'Finish tour creating the tour', ' tour' ) ) . '" title="' . esc_attr( $caption ) . '">' . esc_html( $caption ) . '</a>';
+ return $actions;
+ }
+
+ /**
+ * Add a row action to the tour post type.
+ *
+ * @param array $actions The actions.
+ *
+ * @return array The modified actions.
+ */
+ public static function tour_row_actions( $actions ) {
+ $actions[] = 'Add more steps';
+ return $actions;
+ }
+
+ /**
+ * Get a custom excerpt for the tour post type.
+ *
+ * @param string $excerpt The excerpt.
+ * @param WP_Post $post The post.
+ *
+ * @return string The excerpt.
+ */
+ public static function get_the_excerpt( $excerpt, $post = null ) {
+ if ( get_post_type( $post ) === 'tour' ) {
+ $steps = self::json_decode( $post->post_content );
+ if ( $steps ) {
+ $c = ( count( $steps ) - 1 );
+ return sprintf(
+ // translators: %d is the number of steps.
+ _n( '%d step', '%d steps', $c, 'tour' ),
+ $c
+ );
+ }
+ return '';
+ }
+ return $excerpt;
+ }
+
+ /**
+ * Store the tour as a JSON in the post_content.
+ *
+ * @param array $data The data.
+ * @param array $postarr The postarr.
+ *
+ * @return array The modified data with the tour as JSON.
+ */
+ public static function wp_insert_post_data( $data, $postarr ) {
+ if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'update-post_' . $postarr['ID'] ) ) {
+ return $data;
+ }
+
+ if ( ! isset( $_POST['color'] ) || 'tour' !== $data['post_type'] ) {
+ return $data;
+ }
+
+ $data['post_title'] = sanitize_text_field( $_POST['post_title'] );
+
+ $tour = array(
+ array(
+ 'color' => sanitize_text_field( $_POST['color'] ),
+ 'title' => $data['post_title'],
+ ),
+ );
+
+ if ( isset( $_POST['override_json'] ) ) {
+ $data['post_content'] = $_POST['json'];
+ return $data;
+ }
+
+ if ( isset( $_POST['order'] ) ) {
+ foreach ( $_POST['order'] as $i ) {
+ $step = $_POST['tour'][ $i ];
+
+ if ( '' === trim( $step['element'] ) ) {
+ continue;
+ }
+
+ if ( ! isset( $step['popover'] ) ) {
+ continue;
+ }
+
+ $step['element'] = sanitize_text_field( $step['element'] );
+ foreach ( $step['popover'] as $k => $v ) {
+ if ( 'title' === $k ) {
+ $step['popover'][ $k ] = sanitize_text_field( $step['popover'][ $k ] );
+ } elseif ( 'description' === $k ) {
+ $step['popover'][ $k ] = preg_replace( '/(\s|\x{00a0})+/siu', ' ', nl2br( $step['popover'][ $k ] ) );
+ $step['popover'][ $k ] = wp_kses_post( $step['popover'][ $k ] );
+ } else {
+ unset( $step['popover'][ $k ] );
+ }
+ }
+ $tour[] = $step;
+ }
+ }
+
+ $data['post_content'] = wp_json_encode( wp_slash( $tour ), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
+
+ return $data;
+ }
+
+ /**
+ * Adds a css class 'closed' to the postbox_classes_tour_tour-json.
+ *
+ * This is so that the JSON box is closed by default.
+ *
+ * @param array $classes The classes.
+ *
+ * @return array The modified classes.
+ */
+ public static function add_closed_css_class( $classes ) {
+ $classes[] = 'closed';
+ return $classes;
+ }
+
+ /**
+ * Add the tour-json meta box.
+ */
+ public static function admin_init() {
+ add_meta_box(
+ 'tour-json',
+ 'JSON',
+ function ( $post ) {
+ $tour = self::json_decode( $post->post_content );
+ if ( $tour ) {
+ $json = wp_json_encode( $tour, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT );
+ ?><textarea name="json" style="font-family: monospace; width: 100%" rows="<?php echo esc_attr( min( 50, 2 + count( explode( PHP_EOL, $json ) ) ) ); ?>" onchange="void(document.getElementById('override_json').checked=true)"><?php echo esc_html( $json ); ?></textarea><br/>
+ <label><input type="checkbox" id="override_json" name="override_json" value="1"> <?php esc_html_e( 'Override when saving', 'tour' ); ?></label>
+ <?php
+ }
+ },
+ 'tour',
+ 'side',
+ 'low'
+ );
+ }
+
+ /**
+ * Show the custom tour edit fields after the editor.
+ *
+ * @param WP_Post $post The post.
+ */
+ public static function edit_form_after_editor( $post ) {
+ if ( 'tour' !== get_post_type( $post ) ) {
+ return;
+ }
+ wp_tinymce_inline_scripts();
+
+ $tour = self::json_decode( $post->post_content );
+ if ( ! $tour ) {
+ $color = '#3939c7';
+ $tour = array();
+ } else {
+ $color = $tour[0]['color'];
+ array_shift( $tour );
+ }
+
+ ?>
+ <div style="border: 1px solid #ccc; border-radius: 4px; padding: .5em; margin-top: 2em">
+ <table class="form-table">
+ <tr>
+ <th scope="row"><?php esc_html_e( 'Color', 'tour' ); ?></th>
+ <td>
+ <input type="color" name="color" id="tour_color" value="<?php echo esc_attr( $color ); ?>" />
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div id="steps">
+ <?php
+ foreach ( $tour as $k => $step ) {
+ ?>
+ <div class="step" style="border: 1px solid #ccc; border-radius: 4px; padding: .5em; margin-top: 2em">
+ <input type="hidden" name="order[]" value="<?php echo esc_attr( $k ); ?>"/>
+ <table class="form-table">
+ <tbody>
+ <tr>
+ <th scope="row"><label for="tour-title-<?php echo esc_attr( $k ); ?>"><?php esc_html_e( 'Title', 'tour' ); ?></label><br>
+ </th>
+ <td>
+ <input name="tour[<?php echo esc_attr( $k ); ?>][popover][title]" rows="7" id="tour-step-title-<?php echo esc_attr( $k ); ?>" class="regular-text" value="<?php echo esc_attr( $step['popover']['title'] ); ?>"/>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row"><label for="tour-step-description-<?php echo esc_attr( $k ); ?>"><?php esc_html_e( 'Description', 'tour' ); ?></label></th>
+ <td>
+ <?php
+ wp_editor(
+ $step['popover']['description'],
+ 'tour-step-description-' . $k,
+ array(
+ 'textarea_name' => 'tour[' . $k . '][popover][description]',
+ 'tinymce' => true,
+ 'quicktags' => true,
+ 'editor_height' => 300,
+ 'media_buttons' => true,
+ 'teeny' => true,
+ 'editor_css' => '',
+ 'textarea_rows' => 7,
+ 'drag_drop_upload' => true,
+ 'wpautop' => true,
+ )
+ );
+ ?>
+ </td>
+ </tr>
+ <tr>
+ <th scope="row"><label for="tour-step-element-<?php echo esc_attr( $k ); ?>"><?php esc_html_e( 'CSS Selector', 'tour' ); ?></label></th>
+ <td>
+ <textarea name="tour[<?php echo esc_attr( $k ); ?>][element]" rows="7" id="tour-step-element-<?php echo esc_attr( $k ); ?>" class="large-text code tour-step-css"><?php echo esc_html( is_array( $step['element'] ) ? reset( $step['element'] ) : $step['element'] ); ?></textarea>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <a href="#" class="delete-tour-step" data-delete-text="<?php esc_attr_e( 'Delete', 'tour' ); ?>" data-undo-text="<?php esc_attr_e( 'Undo Delete', 'tour' ); ?>"><?php esc_html_e( 'Delete', 'tour' ); ?></a>
+ <a href="#" class="tour-move-up"><?php esc_html_e( 'Move Up', 'tour' ); ?></a>
+ <a href="#" class="tour-move-down"><?php esc_html_e( 'Move Down', 'tour' ); ?></a>
+
+ </div>
+ <?php
+ }
+ ?>
+ </div>
+ <?php if ( $post->post_title ) : ?>
+ <br/><button id="add-more-steps" class="button"><?php esc_html_e( 'Add Steps', 'tour' ); ?></button>
+ <?php else : ?>
+ <p class="description">
+ Set a title to add tour steps.
+ </p>
+ <?php endif; ?>
+ <style>
+ #driver-popover-content {
+ max-width: none;
+ }
+ </style>
+ <script>
+ document.getElementById('post').addEventListener('submit', function ( event ) {
+ setTourCookie( document.getElementById('post_ID').value );
+ } );
+
+ <?php if ( $post->post_title ) : ?>
+ document.getElementById('add-more-steps').addEventListener('click', function ( event ) {
+ event.preventDefault();
+ setTourCookie( document.getElementById('post_ID').value );
+ const driver = window.driver.js.driver;
+ var driverObj = driver( {
+ showProgress: false,
+ steps: [
+ {
+ element: '#tour-launcher',
+ popover: {
+ title: 'Add your first step',
+ description: 'Click this to enable and disable.',
+ side: 'top'
+ }
+ },
+ {
+ popover: {
+ title: 'Select the element to highlight',
+ description: '<img src="<?php echo esc_url( plugins_url( 'assets/images/select-tour-step.gif', __FILE__ ) ); ?>" alt="<?php esc_attr_e( 'Tour creation mode', 'tour' ); ?>" width="525" height="166" />',
+ side: 'top'
+ }
+ }
+ ]
+ } );
+ driverObj.drive();
+ } );
+ <?php endif; ?>
+ var updateArrows = function() {
+ document.querySelectorAll('.step').forEach( function( element ) {
+ element.querySelector('.tour-move-up').style.display = element.previousElementSibling ? 'inline' : 'none';
+ element.querySelector('.tour-move-down').style.display = element.nextElementSibling ? 'inline' : 'none';
+ });
+ }
+
+ document.addEventListener('click', function( event ) {
+ if ( ! event.target.matches('.tour-move-up') ) {
+ return;
+ }
+ event.preventDefault();
+ var element = event.target.closest('div');
+ var parent = element.parentNode;
+ var prev = element.previousElementSibling;
+ if ( prev ) {
+ parent.insertBefore( element, prev );
+ }
+ updateArrows();
+ });
+
+ document.addEventListener('click', function( event ) {
+ if ( ! event.target.matches('.tour-move-down') ) {
+ return;
+ }
+ event.preventDefault();
+ var element = event.target.closest('div');
+ var parent = element.parentNode;
+ var next = element.nextElementSibling;
+ if ( next ) {
+ parent.insertBefore( next, element );
+ }
+ updateArrows();
+ });
+ updateArrows();
+
+ document.addEventListener('click', function( event ) {
+ if ( ! event.target.matches('.delete-tour-step') ) {
+ return;
+ }
+ event.preventDefault();
+ var t = event.target.closest('div').querySelector('table');
+ var css = t.querySelector('.tour-step-css');
+ if ( t.style.display === 'none' ) {
+ t.style.display = 'table';
+ css.value = css.dataset.oldValue;
+ event.target.textContent = event.target.dataset.deleteText;
+ return;
+ }
+ t.style.display = 'none';
+ css.dataset.oldValue = css.value;
+ css.value = '';
+ event.target.textContent = event.target.dataset.undoText;
+ });
+
+ </script>
+ <?php
+ }
+
+ /**
+ * Add the tours post_type posts via the tour_list hook.
+ *
+ * @param array $tours The tours.
+ *
+ * @return array The augmented tours.
+ */
+ public static function tour_list( $tours ) {
+ $args = array(
+ 'post_type' => 'tour',
+ 'posts_per_page' => -1,
+ );
+
+ if ( current_user_can( 'edit_posts' ) ) {
+ $args['post_status'] = array( 'publish', 'draft' );
+ }
+
+ foreach ( get_posts( $args ) as $tour ) {
+ $tour_steps = self::json_decode( $tour->post_content );
+ if ( ! $tour_steps ) {
+ $tour_steps = array(
+ array(
+ 'title' => $tour->post_title,
+ 'append' => 'draft' === $tour->post_status ? ' (' . _x( 'Draft', 'post status' ) . ')' : '', // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
+ 'color' => '#3939c7',
+ ),
+ );
+ } elseif ( 'draft' === $tour->post_status ) {
+ $tour_steps[0]['append'] = ' (' . _x( 'Draft', 'post status' ) . ')'; // phpcs:ignore WordPress.WP.I18n.MissingArgDomain
+ }
+ $tours[ $tour->ID ] = $tour_steps;
+ }
+
+ return $tours;
+ }
+
+ /**
+ * Adds the tour menu to the sidebar.
+ */
+ public static function add_admin_menu() {
+ add_menu_page( 'Tour', 'Tour', 'edit_posts', 'tour', 'tour', 'dashicons-admin-site-alt3', 6 );
+ add_submenu_page( 'tour', 'Settings', 'Settings', 'edit_posts', 'tour-settings', array( get_called_class(), 'tour_admin_settings' ) );
+ }
+
+ /**
+ * Output the tour settings.
+ */
+ public static function tour_admin_settings() {}
+
+ /**
+ * Outputs the tour button.
+ */
+ public static function output_tour_button() {
+ if ( ! current_user_can( 'edit_posts' ) ) {
+ return;
+ }
+ ?>
+
+ <div id="tour-launcher" style="display: none;">
+ <span class="dashicons dashicons-admin-site-alt3"></span>
+ <span id="tour-title"></span>
+ <br>
+ <span style="float: right">
+ <span id="tour-steps"></span>
+ <a href="">close</a>
+ </span>
+ </div>
+ <?php
+ }
+
+ /**
+ * Outputs the tour list with the ability to reset it.
+ */
+ public static function show_user_profile() {
+ ?>
+ <h2>Tour</h2>
+ <p>Reset your tour progress:</p>
+ <table class="">
+ <thead>
+ <tr>
+ <td>Name</td>
+ <td>Progress</td>
+ <td>Action</td>
+ </tr>
+ </thead>
+ <?php
+ $progress = get_user_option( 'tour-progress', get_current_user_id() );
+ foreach ( apply_filters( 'tour_list', array() ) as $tour_id => $tour ) {
+ $tour_title = $tour[0]['title'];
+ ?>
+ <tr>
+ <td><?php echo esc_html( $tour_title ); ?>:</td>
+ <td class="tour-progress" data-not-started-text="<?php esc_attr_e( 'Not started.', 'tour' ); ?>">
+ <?php
+ if ( isset( $progress[ $tour_id ] ) && $progress[ $tour_id ] ) {
+ echo esc_html( $progress[ $tour_id ] );
+ } else {
+ esc_html_e( 'Not started.', 'tour' );
+ }
+ ?>
+ </td>
+ <td><a href="" class="reset-tour" data-reset-tour-id="<?php echo esc_html( $tour_id ); ?>">Reset</td>
+ </tr>
+ <?php
+ }
+
+ ?>
+ </table>
+ <script>
+ document.addEventListener('click', function( event ) {
+ if ( ! event.target.dataset.resetTourId ) {
+ return;
+ }
+
+ event.preventDefault();
+
+ var xhr = new XMLHttpRequest();
+ xhr.open('POST', tour_plugin.rest_url + 'tour/v1/save-progress');
+ xhr.setRequestHeader('Content-Type', 'application/json');
+ xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
+ xhr.send(JSON.stringify({
+ tour: event.target.dataset.resetTourId,
+ step: -1
+ }));
+ var p = event.target.closest('tr').querySelector('.tour-progress');
+
+ p.textContent = p.dataset.notStartedText;
+
+ } );
+ </script>
+ <?php
+ }
+
+ /**
+ * Shows the tour list.
+ *
+ * @param array $attributes The attributes.
+ *
+ * @return string The content.
+ */
+ public static function show_tour_list( $attributes ) {
+ $tours = apply_filters( 'tour_list', array() );
+ if ( empty( $tours ) ) {
+ return '<p>' . esc_html( $attributes['noToursText'] ) . '</p>';
+ }
+ $tour_list = '<ul id="page-tour-list">';
+ foreach ( $tours as $tour_id => $tour ) {
+ $tour_list .= '<li><a class="tour-list-item" href="" role="button" data-tour-id="' . esc_attr( $tour_id ) . '">' . esc_html( $tour[0]['title'] . ( isset( $tour[0]['append'] ) ? $tour[0]['append'] : '' ) ) . '</a></li>';
+ }
+ $tour_list .= '</ul>';
+
+ return $tour_list;
+ }
+
+ /**
+ * Register the Available Tours block.
+ */
+ public static function register_block_type() {
+ register_block_type(
+ __DIR__ . '/assets/blocks/build',
+ array(
+ 'api_version' => 3,
+ 'attributes' => array(
+ 'noToursText' => array(
+ 'type' => 'string',
+ 'default' => __( 'There are no tours available.', 'tour' ),
+ ),
+ ),
+ 'render_callback' => array( get_called_class(), 'show_tour_list' ),
+ )
+ );
+ }
+
+ /**
+ * Adds the tours menu to masterbar.
+ */
+ public static function add_tours_menu_to_masterbar() {
+ global $wp_admin_bar;
+ $tours = apply_filters( 'tour_list', array() );
+ if ( empty( $tours ) ) {
+ return;
+ }
+ $wp_admin_bar->add_menu(
+ array(
+ 'id' => 'tour-list',
+ 'title' => esc_html__( 'Tours', 'tour' ),
+ 'href' => '#',
+ )
+ );
+
+ foreach ( $tours as $tour_id => $tour ) {
+ $wp_admin_bar->add_menu(
+ array(
+ 'parent' => 'tour-list',
+ 'id' => 'tour-' . esc_html( $tour_id ),
+ 'title' => esc_html( $tour[0]['title'] . ( isset( $tour[0]['append'] ) ? $tour[0]['append'] : '' ) ),
+ 'href' => '#',
+ 'meta' => array(
+ 'class' => 'tour-list-item',
+ ),
+ )
+ );
+ }
+ }
+}
</ins><span class="cx" style="display: block; padding: 0 10px">Property changes on: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/class-tour.php
</span><span class="cx" style="display: block; padding: 0 10px">___________________________________________________________________
</span></span></pre></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: svn:eol-style</h4></div>
<ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+native
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of property
</span><a id="sitestrunkwordpressorgpublic_htmlwpcontentpluginstourtourphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/tour.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/tour.php 2023-11-28 20:53:04 UTC (rev 12981)
+++ sites/trunk/wordpress.org/public_html/wp-content/plugins/tour/tour.php 2023-11-29 13:15:56 UTC (rev 12982)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -8,611 +8,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * Author URI: http://automattic.com/
</span><span class="cx" style="display: block; padding: 0 10px"> * Text Domain: tour
</span><span class="cx" style="display: block; padding: 0 10px"> * License: GPLv2 or later
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ *
+ * @package Tour
</ins><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> defined( 'ABSPATH' ) || die();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+define( 'TOUR_VERSION', '1.0' );
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function tour_enqueue_scripts() {
- static $once = false;
- if ( $once ) {
- return;
- }
- $once = true;
-
- wp_register_style( 'driver-js', plugins_url( 'assets/css/driver-js.css', __FILE__ ), array(), filemtime( __DIR__ . '/assets/css/driver-js.css' ) );
- wp_register_style( 'tour-css', plugins_url( 'assets/css/style.css', __FILE__ ), array(), filemtime( __DIR__ . '/assets/css/style.css' ) );
- wp_enqueue_style( 'driver-js' );
- wp_enqueue_style( 'tour-css' );
- wp_enqueue_script( 'driver-js', plugins_url( 'assets/js/driver-js.js', __FILE__ ), array(), filemtime( __DIR__ . '/assets/js/driver-js.js' ), array( 'in_footer' => true ) );
- wp_register_script( 'tour', plugins_url( 'assets/js/tour.js', __FILE__ ), array( 'driver-js' ), filemtime( __DIR__ . '/assets/js/tour.js' ), false );
- wp_enqueue_script( 'tour' );
- wp_localize_script(
- 'tour',
- 'tour_plugin', array(
- 'tours' => apply_filters( 'tour_list', array() ),
- 'nonce' => wp_create_nonce( 'wp_rest' ),
- 'rest_url' => rest_url(),
- 'progress' => get_user_option( 'tour-progress', get_current_user_id() ),
- )
- );
-
- if ( current_user_can( 'edit_posts' ) ) {
- wp_register_script( 'tour-admin', plugins_url( 'assets/js/tour-admin.js', __FILE__ ), array( 'driver-js' ), filemtime( __DIR__ . '/assets/js/tour-admin.js' ), true );
- wp_enqueue_script( 'tour-admin' );
- }
-}
-
-add_action( 'admin_enqueue_scripts', 'tour_enqueue_scripts' );
-add_action( 'wp_enqueue_scripts', 'tour_enqueue_scripts' );
-add_action( 'gp_head', 'wp_enqueue_scripts' );
-
-function tour_register_post_type() {
- register_post_type(
- 'tour',
- array(
- 'labels' => array(
- 'name' => __( 'Tours', 'tour' ),
- 'singular_name' => __( 'Tour', 'tour' ),
- 'add_new' => __( 'Create New', 'tour' ),
- 'add_new_item' => __( 'Create New Tour', 'tour' ),
- 'edit_item' => __( 'Edit Tour', 'tour' ),
- 'new_item' => __( 'New Tour', 'tour' ),
- 'all_items' => __( 'All Tours', 'tour' ),
- 'view_item' => __( 'View Tour', 'tour' ),
- 'search_items' => __( 'Search Tours', 'tour' ),
- 'not_found' => __( 'No tours found.', 'tour' ),
-
- ),
-
- 'public' => false,
- 'show_ui' => true,
- 'show_in_nav_menus' => true,
- 'show_in_menu' => 'tour',
- 'supports' => array( 'title', 'revisions' ),
- )
- );
-}
-add_action( 'init', 'tour_register_post_type' );
-
-add_action(
- 'rest_api_init',
- function() {
- register_rest_route(
- 'tour/v1',
- 'save-progress',
- array(
- 'methods' => 'POST',
- 'callback' => function( WP_REST_Request $request ) {
- if ( ! is_user_logged_in() ) {
- return array( 'success' => 'logged-out' );
- }
- $step = $request->get_param( 'step' );
- $tour_id = $request->get_param( 'tour' );
-
- $tour = get_post( $tour_id );
- if ( ! $tour || is_wp_error( $tour ) || $tour->post_type !== 'tour' ) {
- return array(
- 'success' => false,
- );
- }
-
- $tour_progress = get_user_option( 'tour-progress', get_current_user_id() );
- if ( ! $tour_progress ) {
- $tour_progress = array();
- }
- if ( $step < 0 || ! is_numeric( $step ) ) {
- unset( $tour_progress[ $tour_id ] );
- } else {
- $tour_progress[ $tour_id ] = $step;
- }
- update_user_option( get_current_user_id(), 'tour-progress', $tour_progress );
- return array(
- 'success' => true,
- );
- },
- )
- );
-
- register_rest_route(
- 'tour/v1',
- 'report-missing',
- array(
- 'methods' => 'POST',
- 'callback' => function( WP_REST_Request $request ) {
- $step = $request->get_param( 'step' );
- $tour_id = $request->get_param( 'tour' );
- $selector = $request->get_param( 'selector' );
- $url = $request->get_param( 'url' );
-
- $tour = get_post( $tour_id );
- if ( ! $tour || is_wp_error( $tour ) || $tour->post_type !== 'tour' ) {
- return array(
- 'success' => false,
- );
- }
-
- if ( $tour ) {
- $missing_steps = get_post_meta( $tour, 'missing_steps', true );
- if ( ! $missing_steps ) {
- $missing_steps = array();
- }
- if ( ! isset( $missing_steps[ $step ] ) ) {
- $missing_steps[ $step ] = array();
- }
- if ( ! isset( $missing_steps[ $step ][ $url ] ) ) {
- $missing_steps[ $step ][ $url ] = array();
- }
- if ( ! isset( $missing_steps[ $step ][ $url ][ $selector ] ) ) {
- $missing_steps[ $step ][ $url ][ $selector ] = 0;
- }
- $missing_steps[ $step ][ $url ][ $selector ] += 1;
- update_post_meta( $tour, 'missing_steps', $missing_steps );
- return array(
- 'success' => true,
- );
- }
- return array(
- 'success' => false,
- );
- },
- )
- );
-
- register_rest_route(
- 'tour/v1',
- 'save',
- array(
- 'methods' => 'POST',
- 'callback' => function( WP_REST_Request $request ) {
- if ( ! current_user_can( 'edit_posts' ) ) {
- return array(
- 'success' => false,
- );
- }
- $steps = json_decode( $request->get_param( 'steps' ), true );
- if ( ! isset( $steps[0]['title'] ) ) {
- return array(
- 'success' => false,
- );
- }
- if ( ! isset( $steps[1]['popover'] ) ) {
- return array(
- 'success' => false,
- );
- }
- $tour_id = $request->get_param( 'tour' );
-
- $tour = get_post( $tour_id );
- if ( ! $tour || is_wp_error( $tour ) || $tour->post_type !== 'tour' ) {
- return array(
- 'success' => false,
- );
- }
-
- if ( $tour ) {
- wp_update_post(
- array(
- 'ID' => $tour_id,
- 'post_content' => json_encode( $steps ),
- 'post_status' => 'publish',
- ),
- true
- );
- }
-
- return $tour_id;
- },
- )
- );
- }
-);
-
-add_filter(
- 'post_row_actions',
- function( $actions, $post ) {
- if ( $post->post_type !== 'tour' || $post->post_status === 'trash' ) {
- return $actions;
- }
-
- $tour_steps = json_decode( wp_unslash( $post->post_content ), true );
- if ( empty( $tour_steps[0]['title'] ) ) {
- return $actions;
- }
-
- $caption = __( 'Add more steps', 'tour' );
-
- $actions['add-more-steps'] = '<a href="' . get_permalink( $post->ID ) . '" data-tour-id="' . esc_attr( $post->ID ) . '" data-add-more-steps-text="' . esc_attr( $caption ) . '" data-finish-tour-creation-text="' . esc_attr( __( 'Finish tour creating the tour',' tour' ) ) . '" title="' . esc_attr( $caption ) . '">' . esc_html( $caption ) . '</a>';
- return $actions;
- }, 10, 2
-);
-
-add_filter(
- 'tour_row_actions',
- function ( $actions, $tag ) {
- $actions[] = 'Add more steps';
- return $actions;
- }, 10, 2
-);
-
-add_filter(
- 'wp_insert_post_data',
- function ( $data, $postarr ) {
- if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'update-post_' . $postarr['ID'] ) ) {
- return $data;
- }
-
- if ( ! isset( $_POST['tour'] ) || ! isset( $_POST['color'] ) || 'tour' !== $data['post_type'] ) {
- return $data;
- }
-
- $data['post_title'] = sanitize_text_field( $_POST['post_title'] );
-
- $tour = array(
- array(
- 'color' => sanitize_text_field( $_POST['color'] ),
- 'title' => $data['post_title'],
- )
- );
-
- if ( isset( $_POST['override_json'] ) ) {
- $data['post_content'] = sanitize_text_field( $_POST['json'] );
- return $data;
- }
-
- if ( isset( $_POST['order'] ) ) {
- foreach ( $_POST['order'] as $i ) {
- $step = $_POST['tour'][$i];
-
- if ( '' === trim( $step['element'] ) ) {
- continue;
- }
-
- if ( ! isset( $step['popover'] ) ) {
- continue;
- }
-
- $step['element'] = sanitize_text_field( $step['element'] );
- foreach ( $step['popover'] as $k => $v ) {
- if ( ! in_array( $k, array( 'title', 'description'))) {
- unset($step['popover'][$k]);
- }
- }
- $tour[] = $step;
- }
- }
-
- $data['post_content'] = wp_json_encode( $tour );
- return $data;
- },
- 10,
- 2
-);
-
-add_action( 'postbox_classes_tour_tour-json', function( $classes ) {
- $classes[] = 'closed';
- return $classes;
-});
-add_action( 'admin_init', function() {
- add_meta_box(
- 'tour-json',
- 'JSON',
- function( $post ) {
- $tour = json_decode( wp_unslash( $post->post_content ), true );
- if ( $tour ) {
- $json = json_encode( $tour, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT );
- ?><textarea name="json" style="font-family: monospace; width: 100%" rows="<?php echo esc_attr( min( 50, 2 + count( explode( PHP_EOL, $json ) ) ) ); ?>"><?php echo esc_html( $json ); ?></textarea><br/>
- <label><input type="checkbox" name="override_json" value="1"> <?php esc_html_e( 'Override when saving', 'tour' ); ?></label>
- <?php
- }
- },
- 'tour',
- 'side',
- 'low'
- );
-} );
-
-add_action( 'edit_form_after_editor', function( $post ) {
- if ( 'tour' !== get_post_type( $post ) ) {
- return;
- }
-
- $tour = json_decode( wp_unslash( $post->post_content ), true );
- if ( ! $tour ) {
- $color = '#3939c7';
- $tour = array();
- } else {
- $color = $tour[0]['color'];
- array_shift( $tour );
- }
-
- ?>
- <div style="border: 1px solid #ccc; border-radius: 4px; padding: .5em; margin-top: 2em">
- <table class="form-table">
- <tr>
- <th scope="row"><?php esc_html_e( 'Color', 'tour' ); ?></th>
- <td>
- <input type="color" name="color" id="tour_color" value="<?php echo esc_attr( $color ); ?>" />
- </td>
- </tr>
- </table>
- </div>
- <div id="steps">
- <?php
- foreach ( $tour as $k => $step ) {
- ?>
- <div class="step" style="border: 1px solid #ccc; border-radius: 4px; padding: .5em; margin-top: 2em">
- <input type="hidden" name="order[]" value="<?php echo esc_attr( $k ); ?>"/>
- <table class="form-table">
- <tbody>
- <tr>
- <th scope="row"><label for="tour-title-<?php echo esc_attr( $k ); ?>"><?php esc_html_e( 'Title', 'tour' ); ?></label><br>
- </th>
- <td>
- <input name="tour[<?php echo esc_attr( $k ); ?>][popover][title]" rows="7" id="tour-step-title-<?php echo esc_attr( $k ); ?>" class="regular-text" value="<?php echo esc_attr( $step['popover']['title'] ); ?>"/>
- </td>
- </tr>
- <tr>
- <th scope="row"><label for="tour-step-description-<?php echo esc_attr( $k ); ?>"><?php esc_html_e( 'Description', 'tour' ); ?></label></th>
- <td>
- <textarea name="tour[<?php echo esc_attr( $k ); ?>][popover][description]" rows="7" id="tour-step-description-<?php echo esc_attr( $k ); ?>" class="large-text"><?php echo esc_html( $step['popover']['description'] ); ?></textarea>
- </td>
- </tr>
- <tr>
- <th scope="row"><label for="tour-step-element-<?php echo esc_attr( $k ); ?>"><?php esc_html_e( 'CSS Selector', 'tour' ); ?></label></th>
- <td>
- <textarea name="tour[<?php echo esc_attr( $k ); ?>][element]" rows="7" id="tour-step-element-<?php echo esc_attr( $k ); ?>" class="large-text code tour-step-css"><?php echo esc_html( is_array( $step['element'] ) ? reset( $step['element'] ) : $step['element'] ); ?></textarea>
- </td>
- </tr>
- </tbody>
- </table>
- <a href="#" class="delete-tour-step" data-delete-text="<?php esc_attr_e( 'Delete', 'tour' ); ?>" data-undo-text="<?php esc_attr_e( 'Undo Delete', 'tour' ); ?>"><?php esc_html_e( 'Delete', 'tour' ); ?></a>
- <a href="#" class="tour-move-up"><?php esc_html_e( 'Move Up', 'tour' ); ?></a>
- <a href="#" class="tour-move-down"><?php esc_html_e( 'Move Down', 'tour' ); ?></a>
-
- </div>
- <?php
- }
- ?>
- </div>
- <?php if ( $post->post_title ) : ?>
- <br/><button id="add-more-steps" class="button"><?php esc_html_e( 'Add Steps', 'tour' ); ?></button>
- <?php else : ?>
- <p class="description">
- Set a title to add tour steps.
- </p>
- <?php endif; ?>
- <style>
- #driver-popover-content {
- max-width: none;
- }
- </style>
- <script>
- document.getElementById('post').addEventListener('submit', function ( event ) {
- setTourCookie( document.getElementById('post_ID').value );
- } );
-
- <?php if ( $post->post_title ) : ?>
- document.getElementById('add-more-steps').addEventListener('click', function ( event ) {
- event.preventDefault();
- setTourCookie( document.getElementById('post_ID').value );
- const driver = window.driver.js.driver;
- var driverObj = driver( {
- showProgress: false,
- steps: [
- {
- element: '#tour-launcher',
- popover: {
- title: 'Add your first step',
- description: 'Click this to enable and disable.',
- side: 'top'
- }
- },
- {
- popover: {
- title: 'Select the element to highlight',
- description: '<img src="<?php echo esc_url( plugins_url( 'assets/images/select-tour-step.gif', __FILE__ ) ); ?>" alt="<?php esc_attr_e( 'Tour creation mode', 'tour' ); ?>" width="525" height="166" />',
- side: 'top'
- }
- }
- ]
- } );
- driverObj.drive();
- } );
- <?php endif; ?>
- var updateArrows = function() {
- document.querySelectorAll('.step').forEach( function( element ) {
- element.querySelector('.tour-move-up').style.display = element.previousElementSibling ? 'inline' : 'none';
- element.querySelector('.tour-move-down').style.display = element.nextElementSibling ? 'inline' : 'none';
- });
- }
-
- document.addEventListener('click', function( event ) {
- if ( ! event.target.matches('.tour-move-up') ) {
- return;
- }
- event.preventDefault();
- var element = event.target.closest('div');
- var parent = element.parentNode;
- var prev = element.previousElementSibling;
- if ( prev ) {
- parent.insertBefore( element, prev );
- }
- updateArrows();
- });
-
- document.addEventListener('click', function( event ) {
- if ( ! event.target.matches('.tour-move-down') ) {
- return;
- }
- event.preventDefault();
- var element = event.target.closest('div');
- var parent = element.parentNode;
- var next = element.nextElementSibling;
- if ( next ) {
- parent.insertBefore( next, element );
- }
- updateArrows();
- });
- updateArrows();
-
- document.addEventListener('click', function( event ) {
- if ( ! event.target.matches('.delete-tour-step') ) {
- return;
- }
- event.preventDefault();
- var t = event.target.closest('div').querySelector('table');
- var css = t.querySelector('.tour-step-css');
- if ( t.style.display === 'none' ) {
- t.style.display = 'table';
- css.value = css.dataset.oldValue;
- event.target.textContent = event.target.dataset.deleteText;
- return;
- }
- t.style.display = 'none';
- css.dataset.oldValue = css.value;
- css.value = '';
- event.target.textContent = event.target.dataset.undoText;
- });
-
- </script>
- <?php
-}
-);
-
-add_filter(
- 'tour_list',
- function( $tour ) {
- $args = array(
- 'post_type' => 'tour',
- 'posts_per_page' => -1,
- );
- if ( current_user_can( 'edit_posts' ) ) {
- $args['post_status'] = array( 'publish', 'draft' );
- }
- $tours = get_posts( $args );
-
- foreach ( $tours as $_tour ) {
- $tour_steps = json_decode( wp_unslash( $_tour->post_content ), true );
- if ( ! $tour_steps ) {
- $tour_steps = array(
- array(
- 'title' => $_tour->post_title,
- 'color' => '#3939c7',
- )
- );
- }
- $tour[ $_tour->ID ] = $tour_steps;
- }
-
- return $tour;
- }
-);
-
-function tour_add_admin_menu() {
- add_menu_page( 'Tour', 'Tour', 'edit_posts', 'tour', 'tour', 'dashicons-admin-site-alt3', 6 );
- add_submenu_page( 'tour', 'Settings', 'Settings', 'edit_posts', 'tour-settings', 'tour_admin_settings' );
-}
-
-add_action( 'admin_menu', 'tour_add_admin_menu' );
-
-function tour_admin_settings() {}
-
-function output_tour_button() {
- if ( ! current_user_can( 'edit_posts' ) ) {
- return;
- }
- ?>
- <style>
- #tour-launcher {
- position: fixed;
- bottom: 76px;
- right: 24px;
- font-size: 13px;
- border: 1px solid #ccc;
- border-radius: 10px;
- background: #fff;
- padding: .5em;
- line-height: 1;
- box-shadow: 0 0 3px #999;
- z-index: 999999;
- }
- #tour-launcher span#tour-title {
- cursor: pointer;
- line-height: 1.3em;
- }
- #tour-launcher span#tour-title:hover {
- text-shadow: 0 0 1px #999;
- }
- </style>
- <div id="tour-launcher" style="display: none;">
- <span class="dashicons dashicons-admin-site-alt3"></span>
- <span id="tour-title"></span>
- <br>
- <span style="float: right">
- <span id="tour-steps"></span>
- <a href="">close</a>
- </span>
- </div>
- <?php
-}
-
-add_action( 'wp_footer', 'output_tour_button' );
-add_action( 'admin_footer', 'output_tour_button' );
-
-add_action('show_user_profile', function() {
- ?>
- <h2>Tour</h2>
- <p>Reset your tour progress:</p>
- <table class="">
- <thead>
- <tr>
- <td>Name</td>
- <td>Progress</td>
- <td>Action</td>
- </tr>
- </thead>
- <?php
- $progress = get_user_option( 'tour-progress', get_current_user_id() );
- foreach ( apply_filters( 'tour_list', array() ) as $tour_id => $tour ) {
- $tour_title = $tour[0]['title'];
- ?>
- <tr>
- <td><?php echo esc_html( $tour_title ); ?>:</td>
- <td class="tour-progress" data-not-started-text="<?php esc_attr_e( 'Not started.', 'tour' ); ?>"><?php
- if ( isset( $progress[$tour_id] ) && $progress[$tour_id] ) {
- echo esc_html( $progress[$tour_id] );
- } else {
- esc_html_e( 'Not started.', 'tour' );
- }
- ?></td>
- <td><a href="" class="reset-tour" data-reset-tour-id="<?php echo esc_html( $tour_id ); ?>">Reset</td>
- </tr>
- <?php
- }
-
- ?>
- </table>
- <script>
-document.addEventListener('click', function( event ) {
- if ( ! event.target.dataset.resetTourId ) {
- return;
- }
-
- event.preventDefault();
-
- var xhr = new XMLHttpRequest();
- xhr.open('POST', tour_plugin.rest_url + 'tour/v1/save-progress');
- xhr.setRequestHeader('Content-Type', 'application/json');
- xhr.setRequestHeader('X-WP-Nonce', tour_plugin.nonce);
- xhr.send(JSON.stringify({
- tour: event.target.dataset.resetTourId,
- step: -1
- }));
- var p = event.target.closest('tr').querySelector('.tour-progress');
-
- p.textContent = p.dataset.notStartedText;
-
-} );
- </script>
- <?php
-} );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+require __DIR__ . '/class-tour.php';
+Tour::register_hooks();
</ins></span></pre>
</div>
</div>
</body>
</html>