Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
.advads-buttonset .advads-button {
margin-left: 0;
margin-right: -.3em;
}
.advads-buttonset .advads-button.advads-ui-state-active {
/*border-color: #0074a2 !important;*/
border-color: #2ea2cc !important;
background: #2ea2cc !important;
color: #fff !important;
box-shadow: none;
border-width: 1px;
}
.advads-button {
text-decoration: none;
display: inline-block;
position: relative;
padding: 0;
line-height: normal;
margin-right: .1em;
cursor: pointer;
vertical-align: middle;
text-align: center;
overflow: visible;
color: #555;
border: 1px solid #d3d3d3;
background: #e6e6e6;
font-weight: normal;
font-family: Verdana,Arial,sans-serif;
font-size: 1.1em;
}
.advads-button .advads-button-text {
display: block;
line-height: normal;
padding: .4em 1em;
}
.advads-accessible {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
.advads-tooltip {
padding: 8px;
position: absolute;
z-index: 9999;
max-width: 300px;
box-shadow: 0 0 5px #aaa;
border-radius: 4px;
border: 2px solid #aaa;
background: #fff;
color: #222;
font-family: Verdana,Arial,sans-serif;
font-size: 14px;
font-weight: normal;
}
.advads-tooltip h4 {
margin: 0;
}
/* jQueryUI autocomplete */
.ui-menu-item:hover {
border: 1px solid #999;
background: #dadada;
color: #212121;
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="70" height="70" viewBox="4.312 5.25 70 70" overflow="visible" xmlns:v="https://vecta.io/nano"><linearGradient id="A" gradientUnits="userSpaceOnUse" x1="39.856" y1="81.911" x2="57.095" y2="52.05"><stop offset="0" stop-color="#8c2100"/><stop offset="1" stop-color="#8c2100" stop-opacity="0"/></linearGradient><path fill="url(#A)" d="M46.392 45.871L35.33 65.031c-3.412 5.911-8.94 9.101-12.354 7.135 1.368.788 3.436 1.295 4.87 1L73.971 61.8 46.392 45.871z"/><path fill="#fff" d="M52.296 7.117l-1.759-1.016c-.976-.564-2.076-.85-3.271-.85-1.574 0-3.224.49-4.901 1.458l-12.356 7.134c-2.636 1.523-5.089 4.1-6.909 7.256L7.13 48.751c-4.023 6.971-3.701 14.436.732 16.995l12.353 7.134 1.762 1.018c.978.562 2.077.848 3.269.848 4.123 0 8.761-3.421 11.817-8.715L53.03 38.374c1.823-3.154 2.828-6.567 2.828-9.608V14.503c-.001-3.439-1.265-6.062-3.562-7.386z"/><path d="M8.862 64.014c-3.41-1.969-3.41-8.354 0-14.263l15.971-27.654c1.704-2.956 3.939-5.23 6.176-6.523l12.355-7.133c2.234-1.288 4.47-1.593 6.173-.608s2.561 3.073 2.561 5.654V27.75c0 2.583-.854 5.654-2.561 8.608L33.569 64.014c-2.729 4.729-6.812 7.715-10.084 7.715-.818 0-1.586-.187-2.269-.58L8.862 64.014zM54.695 29.25c0 2.583-.854 5.654-2.561 8.608L36.167 65.514c-3.373 5.845-8.812 9.02-12.234 7.19 3.615-.25 7.779-3.472 10.502-8.19l15.968-27.656c1.737-3.009 2.694-6.244 2.694-9.108V13.487c0-1.574-.291-2.945-.837-4.066 1.618 1.015 2.435 3.053 2.435 5.566V29.25z" fill="#cc3000"/><path d="M46.449 13.182c-.341-.197-.725-.291-1.134-.291-.613 0-1.283.21-1.951.596-1.117.645-2.235 1.782-3.087 3.261-1.706 2.954-1.709 6.148-.003 7.133.341.197.725.291 1.134.291 1.635 0 3.677-1.495 5.041-3.858.855-1.478 1.28-3.013 1.28-4.304s-.424-2.336-1.28-2.828zm-.865 6.63c-1.274 2.206-3.064 3.359-4.176 3.359a1.23 1.23 0 0 1-.634-.157c-.235-.136-.414-.379-.547-.686a5.47 5.47 0 0 0 .879-.472c-.211-.632-.194-2.208.903-4.109.641-1.114 1.499-2.035 2.354-2.529.326-.188.566-.264.734-.299l.032-.411c0-.213-.038-.4-.062-.597l.247-.022c.24 0 .454.053.633.157.497.286.781 1.001.781 1.962.001 1.16-.416 2.547-1.144 3.804zM30.138 49.288c-1.521-.883-3.996.547-5.521 3.189-1.521 2.637-1.521 5.492 0 6.369 1.525.883 3.996-.544 5.521-3.186s1.525-5.495 0-6.372zm-4.139 7.17c-.759-.438-.759-1.868 0-3.187.766-1.321 1.998-2.033 2.76-1.595s.76 1.868 0 3.186-1.997 2.034-2.76 1.596zm4.142-22.946c-1.524-.88-3.996.548-5.518 3.188-1.528 2.641-1.524 5.494 0 6.374s3.993-.548 5.518-3.188 1.525-5.493 0-6.374zm-4.139 7.171c-.762-.438-.762-1.868 0-3.186s1.999-2.033 2.76-1.595.763 1.868-.003 3.186-1.994 2.035-2.757 1.595zm12.764.06L16.019 53.881l-.003-2.252 22.75-13.138z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.532 1 80.123V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.469 99 19.878V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.878V98H19.878C10.019 98 2 89.98 2 80.123V2h78.122m0-2H2a2 2 0 0 0-2 2v78.123C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.878C100 8.917 91.083 0 80.122 0h0zM34.065 47.149H19.381c-.811 0-1.467-.657-1.467-1.467V31c0-.81.656-1.467 1.467-1.467h14.685c.811 0 1.467.657 1.467 1.467v14.683a1.47 1.47 0 0 1-1.468 1.466zm46.637 0H66.019c-.811 0-1.467-.657-1.467-1.467V31c0-.81.656-1.467 1.467-1.467h14.684c.811 0 1.467.657 1.467 1.467v14.683a1.47 1.47 0 0 1-1.468 1.466zm-23.318 0H42.699c-.811 0-1.467-.657-1.467-1.467V31c0-.81.656-1.467 1.467-1.467h14.685c.811 0 1.467.657 1.467 1.467v14.683c0 .81-.657 1.466-1.467 1.466zM34.065 70.467H19.381c-.811 0-1.467-.656-1.467-1.467V54.317c0-.811.656-1.467 1.467-1.467h14.685c.811 0 1.467.656 1.467 1.467V69a1.47 1.47 0 0 1-1.468 1.467zm46.637 0H66.019c-.811 0-1.467-.656-1.467-1.467V54.317c0-.811.656-1.467 1.467-1.467h14.684c.811 0 1.467.656 1.467 1.467V69a1.47 1.47 0 0 1-1.468 1.467zm-23.318 0H42.699c-.811 0-1.467-.656-1.467-1.467V54.317c0-.811.656-1.467 1.467-1.467h14.685c.811 0 1.467.656 1.467 1.467V69c0 .811-.657 1.467-1.467 1.467z" fill="#0074a2"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.532 1 80.123V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.469 99 19.878V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.878V98H19.878C10.019 98 2 89.98 2 80.123V2h78.122m0-2H2a2 2 0 0 0-2 2v78.123C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.878C100 8.917 91.083 0 80.122 0h0zM34.064 45.483H19.38c-.811 0-1.467-.657-1.467-1.467V29.333c0-.81.656-1.467 1.467-1.467h14.685c.811 0 1.467.657 1.467 1.467v14.683a1.47 1.47 0 0 1-1.468 1.467zm46.638 0H66.017c-.811 0-1.467-.657-1.467-1.467V29.333c0-.81.656-1.467 1.467-1.467h14.686c.811 0 1.467.657 1.467 1.467v14.683a1.47 1.47 0 0 1-1.468 1.467zM67.483 42.55h11.752V30.8H67.483v11.75zm-10.1 2.933H42.698c-.811 0-1.467-.657-1.467-1.467V29.333c0-.81.656-1.467 1.467-1.467h14.685c.811 0 1.467.657 1.467 1.467v14.683c0 .811-.657 1.467-1.467 1.467zM44.165 42.55h11.751V30.8H44.165v11.75zm-1.901 11.877c-.23 0-.461.06-.667.179-.412.238-.667.679-.667 1.155v14.682c0 .477.255.917.667 1.155.206.119.437.179.667.179s.46-.06.667-.179l12.718-7.34c.412-.238.667-.679.667-1.155s-.255-.917-.667-1.155l-12.718-7.342c-.206-.12-.437-.179-.667-.179h0zm15.553 17.482c-.811 0-1.467-.656-1.467-1.467V55.761c0-.811.656-1.467 1.467-1.467s1.467.656 1.467 1.467v14.682c0 .81-.656 1.466-1.467 1.466z" fill="#0074a2"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.532 1 80.123V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.469 99 19.878V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.878V98H19.878C10.019 98 2 89.98 2 80.123V2h78.122m0-2H2a2 2 0 0 0-2 2v78.123C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.878C100 8.917 91.083 0 80.122 0h0zM34.064 45.483H19.38a1.47 1.47 0 0 1-1.467-1.467V29.333a1.47 1.47 0 0 1 1.467-1.467h14.684a1.47 1.47 0 0 1 1.467 1.467v14.683c0 .811-.657 1.467-1.467 1.467zM20.847 42.55h11.75V30.8h-11.75v11.75zm59.854 2.933H66.018c-.811 0-1.467-.657-1.467-1.467V29.333c0-.81.656-1.467 1.467-1.467h14.684c.811 0 1.467.657 1.467 1.467v14.683a1.47 1.47 0 0 1-1.468 1.467zm-23.318 0H42.699a1.47 1.47 0 0 1-1.467-1.467V29.333a1.47 1.47 0 0 1 1.467-1.467h14.684c.811 0 1.467.657 1.467 1.467v14.683c0 .811-.657 1.467-1.467 1.467zM44.166 42.55h11.75V30.8h-11.75v11.75zm22.896 27.259l-8.193-4.729c-.227-.133-.505-.133-.733 0a.73.73 0 0 0-.366.635v3.263h-1.016c-1.571-.002-3.046-.613-4.154-1.721l-4.154-4.154 4.154-4.154c1.109-1.109 2.584-1.72 4.152-1.72h1.018v3.263c0 .262.14.504.366.635a.73.73 0 0 0 .367.099c.127 0 .253-.032.366-.099l8.193-4.729a.73.73 0 0 0 .367-.635c0-.262-.14-.504-.367-.635l-8.193-4.73c-.227-.131-.505-.131-.733 0a.73.73 0 0 0-.366.635v3.263h-1.018a8.75 8.75 0 0 0-6.227 2.578l-4.154 4.154-4.155-4.155a8.75 8.75 0 0 0-6.225-2.577h-1.688c-.81 0-1.467.656-1.467 1.467s.657 1.467 1.467 1.467h1.688a5.83 5.83 0 0 1 4.15 1.719l4.155 4.155-4.154 4.154c-1.108 1.107-2.583 1.719-4.15 1.721h-1.688c-.81 0-1.467.656-1.467 1.467s.657 1.467 1.467 1.467h1.689c2.352-.002 4.562-.919 6.223-2.58l4.154-4.154 4.154 4.154c1.661 1.661 3.872 2.578 6.227 2.58h1.018v3.263c0 .262.14.504.366.635a.73.73 0 0 0 .367.099c.127 0 .253-.032.366-.099l8.193-4.729a.73.73 0 0 0 .367-.635c0-.262-.139-.508-.366-.638z" fill="#0074a2"/></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" overflow="visible"><path fill="#fff" d="M19.878 99C9.469 99 1 90.532 1 80.123V2a1 1 0 0 1 1-1h78.122C90.531 1 99 9.469 99 19.878V98a1 1 0 0 1-1 1H19.878z"/><path d="M80.122 2C89.98 2 98 10.02 98 19.878V98H19.878C10.019 98 2 89.98 2 80.123V2h78.122m0-2H2a2 2 0 0 0-2 2v78.123C0 91.083 8.917 100 19.878 100H98a2 2 0 0 0 2-2V19.878C100 8.917 91.083 0 80.122 0h0zm.579 31.367H67.484V24.2c0-.81-.656-1.467-1.467-1.467H34.064c-.811 0-1.467.657-1.467 1.467v7.167H19.38c-.811 0-1.467.657-1.467 1.467v14.683c0 .81.656 1.467 1.467 1.467h13.218v7.167c0 .811.656 1.467 1.467 1.467h31.953c.811 0 1.467-.656 1.467-1.467v-7.167h13.217c.811 0 1.467-.657 1.467-1.467V32.834a1.47 1.47 0 0 0-1.468-1.467zM20.847 46.05V34.3h11.751v11.75H20.847zm58.387 0h-11.75V34.3h11.75v11.75zM50 65.25c-3.235 0-5.867 2.632-5.867 5.867s2.632 5.868 5.867 5.868 5.866-2.632 5.866-5.868S53.234 65.25 50 65.25h0zm17.603 2.934c1.621 0 2.934 1.313 2.934 2.934s-1.312 2.935-2.934 2.935-2.933-1.313-2.933-2.935a2.93 2.93 0 0 1 2.933-2.934m0-2.934c-3.234 0-5.866 2.632-5.866 5.867s2.632 5.868 5.866 5.868 5.867-2.632 5.867-5.868-2.632-5.867-5.867-5.867h0zm-35.207 2.934c1.62 0 2.933 1.313 2.933 2.934s-1.312 2.935-2.933 2.935-2.934-1.313-2.934-2.935 1.313-2.934 2.934-2.934m0-2.934c-3.235 0-5.867 2.632-5.867 5.867s2.632 5.868 5.867 5.868 5.866-2.632 5.866-5.868-2.631-5.867-5.866-5.867h0z" fill="#0074a2"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 B

View File

@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 351.7 352" xml:space="preserve"><path d="M252.2 149.6v125.1h-174.9v-174.9H202.4c-5.2-11.8-8-24.7-8-38.5s3-26.7 8-38.5h-37.7H0v267.9l8.8 8.8 -8.8-8.8C0 324.5 27.5 352 61.3 352l0 0h103.4 164.5V149.3c-11.8 5.2-25 8.3-38.8 8.3C276.9 157.6 264 154.6 252.2 149.6z" fill="#1C1B3A"/><circle cx="290.4" cy="61.3" r="61.3" fill="#0E75A4"/></svg>

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="35px" viewBox="0 0 20 35" overflow="visible" enable-background="new 0 0 20 35" xml:space="preserve">
<defs>
</defs>
<rect fill="#CC3000" width="20" height="35"/>
<polygon fill="#D13607" points="0,0 10.017,5.828 20,0 "/>
<polygon fill="#D13607" points="10.017,17.5 20,11.672 20,23.345 "/>
<polygon fill="#D13607" points="0,23.345 0,11.672 10.017,17.5 "/>
<polygon fill="#C52E00" points="20,0 10.017,5.828 10.017,17.5 20,11.672 "/>
<polygon fill="#D13607" points="0,35 10.017,29.155 20,35 "/>
<polygon fill="#C52E00" points="10.017,17.5 0,23.345 0,35 10.017,29.155 "/>
</svg>

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="35px" viewBox="0 0 20 35" overflow="visible" enable-background="new 0 0 20 35" xml:space="preserve">
<defs>
</defs>
<rect fill="#0074A2" width="20" height="35"/>
<polygon fill="#0A7BA8" points="0,0 10.017,5.828 20,0 "/>
<polygon fill="#0A7BA8" points="10.017,17.5 20,11.672 20,23.345 "/>
<polygon fill="#0A7BA8" points="0,23.345 0,11.672 10.017,17.5 "/>
<polygon fill="#00719D" points="20,0 10.017,5.828 10.017,17.5 20,11.672 "/>
<polygon fill="#0A7BA8" points="0,35 10.017,29.155 20,35 "/>
<polygon fill="#00719D" points="10.017,17.5 0,23.345 0,35 10.017,29.155 "/>
</svg>

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -0,0 +1,35 @@
window.advads_adblocker_image_data = [
'ad',
'bottom-ads',
'bottom_ad',
'logoads',
'movie',
'x28',
'x2x8',
'malwarebytes-banner',
'728x90',
'betindia',
'worldfirst-currencyconversion',
'ml',
'p2',
'clicktoplay',
'download_ad',
'301',
'banner',
'download-bukkake',
'ad2',
'advertise-img',
'bblogo',
'adtech',
'AppStateBanner',
'ads3',
'banner_member',
'adguard-banner',
'mad_ad',
'hdsale',
'porndude',
'1001505_banner',
'Q1-23-CD-Promo-Banner-A',
'500x100',
'300x250',
];

View File

@@ -0,0 +1,445 @@
/* eslint-disable no-unused-vars */
/* eslint-disable camelcase */
/*
* global js functions for Advanced Ads
*/
jQuery(document).ready(function () {
/**
* ADMIN NOTICES
*/
// close button
// .advads-notice-dismiss class can be used to add a custom close button (e.g., link)
jQuery(document).on(
'click',
'.advads-admin-notice .notice-dismiss, .advads-notice-dismiss',
function (event) {
event.preventDefault();
const messagebox = jQuery(this).parents('.advads-admin-notice');
if (messagebox.attr('data-notice') === undefined) return;
const query = {
action: 'advads-close-notice',
notice: messagebox.attr('data-notice'),
nonce: advadsglobal.ajax_nonce,
};
// send query
jQuery.post(ajaxurl, query, function (r) {
messagebox.fadeOut();
});
}
);
// hide notice for 7 days
jQuery(document).on(
'click',
'.advads-admin-notice .advads-notice-hide',
function () {
const messagebox = jQuery(this).parents('.advads-admin-notice');
if (messagebox.attr('data-notice') === undefined) return;
const query = {
action: 'advads-hide-notice',
notice: messagebox.attr('data-notice'),
nonce: advadsglobal.ajax_nonce,
};
// send query
jQuery.post(ajaxurl, query, function (r) {
messagebox.fadeOut();
});
}
);
// autoresponder button
jQuery('body').on('click', '.advads-notices-button-subscribe', function () {
if (this.dataset.notice === undefined) {
return;
}
const messageboxes = jQuery(this).parents('.advads-admin-notice');
if (!messageboxes.length) {
return;
}
const $messagebox = jQuery(messageboxes[0]);
jQuery('<span class="spinner advads-spinner"></span>').insertAfter(
this
);
const query = {
action: 'advads-subscribe-notice',
notice: this.dataset.notice,
nonce: advadsglobal.ajax_nonce,
};
// send and replace with server message
jQuery
.post(ajaxurl, query)
.success(function (response) {
$messagebox
.children('.advads-notice-box_wrapper')
.html('<p>' + response.data.message + '</p>');
$messagebox.addClass('notice-success notice');
})
.fail(function (response) {
$messagebox
.children('.advads-notice-box_wrapper')
.html('<p>' + response.responseJSON.data.message + '</p>');
$messagebox.addClass('notice-error notice');
})
.always(function () {
$messagebox.removeClass('notice-info');
});
});
/**
* Functions for Ad Health Notifications in the backend
*/
// hide button (adds item to "ignore" list)
jQuery(document).on('click', '.advads-ad-health-notice-hide', function () {
const notice = jQuery(this).parents('li');
if (notice.attr('data-notice') === undefined) return;
// var list = notice.parent( 'ul' );
const remove = jQuery(this).hasClass('remove');
// fix height to prevent the box from going smaller first, then show the "show" link and grow again
const notice_box = jQuery('#advads_overview_notices');
notice_box.css('height', notice_box.height() + 'px');
const query = {
action: 'advads-ad-health-notice-hide',
notice: notice.attr('data-notice'),
nonce: advadsglobal.ajax_nonce,
};
// fade out first or remove, so users cant click twice
if (remove) {
notice.remove();
} else {
notice.hide();
}
// show loader
notice_box.find('.advads-loader').show();
advads_ad_health_maybe_remove_list();
// send query
jQuery.post(ajaxurl, query, function (r) {
// update number in menu
advads_ad_health_reload_number_in_menu();
// update show button
advads_ad_health_reload_show_link();
// remove the fixed height
jQuery('#advads_overview_notices').css('height', '');
// remove loader
notice_box.find('.advads-loader').hide();
});
});
// show all hidden notices
jQuery(document).on(
'click',
'.advads-ad-health-notices-show-hidden',
function () {
advads_ad_health_show_hidden();
}
);
/**
* DEACTIVATION FEEDBACK FORM
*/
// show overlay when clicked on "deactivate"
const advads_deactivate_link = jQuery(
'.wp-admin.plugins-php tr[data-slug="advanced-ads"] .row-actions .deactivate a'
);
const advads_deactivate_link_url = advads_deactivate_link.attr('href');
advads_deactivate_link.on('click', function (e) {
e.preventDefault();
// only show feedback form once per 30 days
const c_value = advads_admin_get_cookie(
'advanced_ads_hide_deactivate_feedback'
);
if (c_value === undefined) {
jQuery('#advanced-ads-feedback-overlay').show();
} else {
// click on the link
window.location.href = advads_deactivate_link_url;
}
});
// show text fields
jQuery('#advanced-ads-feedback-content input[type="radio"]').on(
'click',
function () {
// show text field if there is one
jQuery(this)
.parents('li')
.next('li')
.children('input[type="text"], textarea')
.show();
}
);
// handle technical issue feedback in particular
jQuery('#advanced-ads-feedback-content .advanced_ads_disable_help_text').on(
'focus',
function () {
// show text field if there is one
jQuery(this)
.parents('li')
.siblings('.advanced_ads_disable_reply')
.show();
}
);
// send form or close it
jQuery('#advanced-ads-feedback-content .button').on('click', function (e) {
e.preventDefault();
const self = jQuery(this);
// set cookie for 30 days
advads_store_feedback_cookie();
// save if plugin should be disabled
const disable_plugin = self.hasClass(
'advanced-ads-feedback-not-deactivate'
)
? false
: true;
// hide the content of the feedback form
jQuery('#advanced-ads-feedback-content form').hide();
if (self.hasClass('advanced-ads-feedback-submit')) {
// show feedback message
jQuery('#advanced-ads-feedback-after-submit-waiting').show();
if (disable_plugin) {
jQuery(
'#advanced-ads-feedback-after-submit-disabling-plugin'
).show();
}
jQuery.ajax({
type: 'POST',
url: ajaxurl,
dataType: 'json',
data: {
action: 'advads_send_feedback',
feedback: self.hasClass(
'advanced-ads-feedback-not-deactivate'
)
? true
: false,
formdata: jQuery(
'#advanced-ads-feedback-content form'
).serialize(),
},
complete(MLHttpRequest, textStatus, errorThrown) {
// deactivate the plugin and close the popup with a timeout
setTimeout(function () {
jQuery('#advanced-ads-feedback-overlay').remove();
}, 2000);
if (disable_plugin) {
window.location.href = advads_deactivate_link_url;
}
},
});
} else {
// currently not reachable
jQuery('#advanced-ads-feedback-overlay').remove();
window.location.href = advads_deactivate_link_url;
}
});
// close form and disable the plugin without doing anything
jQuery('.advanced-ads-feedback-only-deactivate').on('click', function () {
// hide the content of the feedback form
jQuery('#advanced-ads-feedback-content form').hide();
// show feedback message
jQuery('#advanced-ads-feedback-after-submit-goodbye').show();
jQuery('#advanced-ads-feedback-after-submit-disabling-plugin').show();
// set cookie for 30 days
advads_store_feedback_cookie();
// wait one second
setTimeout(function () {
jQuery('#advanced-ads-feedback-overlay').hide();
window.location.href = advads_deactivate_link_url;
}, 1000);
});
// close button for feedback form
jQuery('#advanced-ads-feedback-overlay-close-button').on(
'click',
function () {
jQuery('#advanced-ads-feedback-overlay').hide();
}
);
jQuery('.advads-help').on('mouseenter', function (event) {
const tooltip = jQuery(event.target).children('.advads-tooltip')[0];
if (typeof tooltip === 'undefined') {
return;
}
// reset inline styles before getting bounding client rect.
tooltip.style.position = '';
tooltip.style.left = '';
tooltip.style.top = '';
const topParentRect = document
.getElementById('wpbody')
.getBoundingClientRect(),
helpRect = event.target.getBoundingClientRect(),
offsets = {
left: Math.ceil(helpRect.left) + 13,
top: Math.ceil(helpRect.top) + 13,
};
let tooltipRect = tooltip.getBoundingClientRect();
tooltip.style.position = 'fixed';
tooltip.style.left = offsets.left + 'px';
tooltip.style.top = offsets.top + 'px';
// check element is not overflowing to the right.
while (tooltipRect.right > topParentRect.right - 20) {
offsets.left -= 10;
tooltip.style.left = offsets.left + 'px';
tooltipRect = tooltip.getBoundingClientRect();
}
// check element is not overflowing bottom of parent and is within viewport.
while (tooltipRect.bottom > Math.min(topParentRect.bottom, jQuery(window).height()) - 20) {
offsets.top -= 10;
tooltip.style.top = offsets.top + 'px';
tooltipRect = tooltip.getBoundingClientRect();
}
});
});
// remove duplicate close buttons
jQuery(window).on('load', function () {
jQuery('a.notice-dismiss').next('button.notice-dismiss').remove();
});
function advads_admin_get_cookie(name) {
let i, x, y;
const ADVcookies = document.cookie.split(';');
for (i = 0; i < ADVcookies.length; i++) {
x = ADVcookies[i].substr(0, ADVcookies[i].indexOf('='));
y = ADVcookies[i].substr(ADVcookies[i].indexOf('=') + 1);
x = x.replace(/^\s+|\s+$/g, '');
if (x === name) {
return unescape(y);
}
}
}
/**
* Store a cookie for 30 days
* The cookie prevents the feedback form from showing multiple times
*/
function advads_store_feedback_cookie() {
const exdate = new Date();
exdate.setSeconds(exdate.getSeconds() + 2592000);
document.cookie =
'advanced_ads_hide_deactivate_feedback=1; expires=' +
exdate.toUTCString() +
'; path=/';
}
/**
* Ad Health Notices in backend
*/
// display notices list (deprecated because we load it without AJAX now)
function advads_display_ad_health_notices() {
const query = {
action: 'advads-ad-health-notice-display',
nonce: advadsglobal.ajax_nonce,
};
const widget = jQuery('#advads_overview_notices .main');
// add loader icon to the widget
widget.html('<span class="advads-loader"></span>');
// send query
jQuery.post(ajaxurl, query, function (r) {
widget.html(r);
// update number in menu
advads_ad_health_reload_number_in_menu();
// update list headlines
advads_ad_health_maybe_remove_list();
// remove widget, if return is empty
if (r === '') {
jQuery('#advads_overview_notices').remove();
}
});
}
// push a notice to the queue
function advads_push_notice(key, attr = '') {
const query = {
action: 'advads-ad-health-notice-push-adminui',
key,
attr,
nonce: advadsglobal.ajax_nonce,
};
// send query
jQuery.post(ajaxurl, query, function (r) {});
}
// show notices of a given type again
function advads_ad_health_show_hidden() {
const notice_box = jQuery('#advads__overview_notices');
const query = {
action: 'advads-ad-health-notice-unignore',
nonce: advadsglobal.ajax_nonce,
};
// show all hidden
jQuery(document)
.find('#advads_overview_notices .advads-ad-health-notices > li:hidden')
.show();
// show loader
notice_box.find('.advads-loader').show();
// update the button
advads_ad_health_reload_show_link();
advads_ad_health_maybe_remove_list();
// send query
jQuery.post(ajaxurl, query, function (r) {
// update issue count
advads_ad_health_reload_number_in_menu();
// hide loader
notice_box.find('.advads-loader').hide();
});
}
// hide list fragments if last item was hidden/removed
function advads_ad_health_maybe_remove_list() {
// get all lists
const lists = jQuery(document).find(
'#advads_overview_notices .advads-ad-health-notices'
);
// check each list separately
lists.each(function (index) {
const list = jQuery(this);
// check if there are visible items in the list
if (list.find('li:visible').length) {
// show parent headline
list.prev('h3').show();
} else {
// hide parent headline
list.prev('h3').hide();
}
});
}
// reload number of notices shown in the sidebar based on element in the problems list
function advads_ad_health_reload_number_in_menu() {
// get number of notices
const number = jQuery(document).find(
'#advads_overview_notices .advads-ad-health-notices > li:visible'
).length;
jQuery('#toplevel_page_advanced-ads .update-count').html(number);
}
// update show X issues link number and visibility
function advads_ad_health_reload_show_link() {
// get number of invisible elements
const number = jQuery(document).find(
'#advads_overview_notices .advads-ad-health-notices > li:hidden'
).length;
const show_link = jQuery('.advads-ad-health-notices-show-hidden');
// update number in the link
jQuery('.advads-ad-health-notices-show-hidden .count').html(number);
// hide of show, depending on number
if (0 === number) {
show_link.hide();
} else {
show_link.show();
}
}
//Radio Toggle visibility
function toggle_visibility(currentElement, toggleElement) {
jQuery(toggleElement).toggle(jQuery(currentElement).val() === 'on');
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
var advanced_ads_adblocker_test = true;

View File

@@ -0,0 +1,534 @@
/**
* Logic for Display and Visitor Conditions forms
*/
jQuery(document).ready(function ($) {
/**
* Pressing the button to add a new condition to the list of conditions
*/
$('.advads-conditions-new select').on('change', function () {
// get the form fieldset and values.
const condition_form_container = $(this).parents('fieldset');
const condition_type = condition_form_container
.find('.advads-conditions-new select')
.val();
const condition_title = condition_form_container
.find('.advads-conditions-new select option:selected')
.text();
let condition_index = parseInt(
condition_form_container.find('.advads-conditions-index').val()
);
const condition_list_target_ID = $.escapeSelector(
condition_form_container.data('condition-list-target')
); // ID of the container into which the new condition is loaded.
const condition_list_target = $('#' + condition_list_target_ID); // container into which the new condition is loaded.
const conditions_form_name = condition_form_container.data(
'condition-form-name'
); // name prefix for the form.
const conditions_connector_default = condition_form_container.data(
'condition-connector-default'
); // default connector option.
const conditions_action =
condition_form_container.data('condition-action'); // action to which to send the AJAX call to.
if (!condition_type || '' == condition_type) {
return;
}
condition_form_container.find('.advads-loader').show(); // show loader.
$.ajax({
type: 'POST',
url: ajaxurl,
data: {
action: conditions_action,
type: condition_type,
index: condition_index,
form_name: conditions_form_name,
nonce: advadsglobal.ajax_nonce,
},
success(r, textStatus, XMLHttpRequest) {
// add.
if (r) {
if ('or' === conditions_connector_default) {
// as used for display conditions.
var connector =
'<input style="display:none;" type="checkbox" name="' +
conditions_form_name +
'[' +
condition_index +
'][connector]" checked="checked" value="or" id="advads-conditions-' +
condition_list_target_ID +
'-' +
condition_index +
'-connector"><label for="advads-conditions-' +
condition_list_target_ID +
'-' +
condition_index +
'-connector">' +
advadstxt.condition_or +
'</label>';
var newline =
'<tr class="advads-conditions-connector advads-conditions-connector-or"><td colspan="3">' +
connector +
'</td></tr><tr><td class="advads-conditions-type" data-condition-type="' +
condition_type +
'">' +
condition_title +
'</td><td>' +
r +
'</td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>';
} else {
// as used for visitor conditions.
var connector =
'<input type="checkbox" name="' +
conditions_form_name +
'[' +
condition_index +
'][connector]" value="or" id="advads-conditions-' +
condition_list_target_ID +
'-' +
condition_index +
'-connector"><label for="advads-conditions-' +
condition_list_target_ID +
'-' +
condition_index +
'-connector">' +
advadstxt.condition_and +
'</label>';
var newline =
'<tr class="advads-conditions-connector advads-conditions-connector-and"><td colspan="3">' +
connector +
'</td></tr><tr><td class="advads-conditions-type" data-condition-type="' +
condition_type +
'">' +
condition_title +
'</td><td>' +
r +
'</td><td><button type="button" class="advads-conditions-remove button">x</button></td></tr>';
}
condition_list_target.find('tbody').append(newline);
condition_list_target
.find(
'tbody .advads-conditions-single.advads-buttonset'
)
.advads_buttonset();
condition_list_target
.find('tbody .advads-conditions-connector input')
.advads_button();
// increase count.
condition_index++;
condition_form_container
.find('.advads-conditions-index')
.val(condition_index);
// reset select.
condition_form_container.find(
'.advads-conditions-new select'
)[0].selectedIndex = 0;
advads_display_condition_option_not_selected();
const tr = $(this).parents('.advads-conditions-table tr');
condition_list_target.next('input').remove();
}
},
error(MLHttpRequest, textStatus, errorThrown) {
condition_form_container
.find('.advads-conditions-new')
.append(errorThrown);
},
complete(MLHttpRequest, textStatus) {
condition_form_container
.find('.advads-conditions-new .advads-loader')
.hide(); // hide loader.
},
});
});
// disable term in the term list of the appropriate condition by just clicking on it.
$(document).on(
'click',
'.advads-conditions-terms-buttons .button',
function (e) {
$(this).remove();
}
);
// display input field to search for terms.
$(document).on(
'click',
'.advads-conditions-terms-show-search',
function (e) {
e.preventDefault();
// display input field.
$(this).siblings('.advads-conditions-terms-search').show().focus();
// register autocomplete.
advads_register_terms_autocomplete(
$(this).siblings('.advads-conditions-terms-search')
);
$(this).next('br').show();
$(this).hide();
}
);
// function for autocomplete.
function advads_register_terms_autocomplete(self) {
self.autocomplete({
classes: {
'ui-autocomplete': 'advads-ui-autocomplete',
},
source(request, callback) {
// var searchField = request.term;
advads_term_search(self, callback);
},
minLength: 1,
select(event, ui) {
// append new line with input fields.
$(
'<label class="button advads-button advads-ui-state-active"><span class="advads-button-text">' +
ui.item.label +
'<input type="hidden" name="' +
self.data('inputName') +
'" value="' +
ui.item.value +
'"></span></label>'
).appendTo(self.siblings('.advads-conditions-terms-buttons'));
// show / hide other elements
// $( '.advads-display-conditions-individual-post' ).hide();
// $( '.advads-conditions-postids-list .show-search a' ).show();
},
// eslint-disable-next-line no-unused-vars
close(event, ui) {
self.val('');
},
});
}
// remove author from list by clicking on it.
$(document).on(
'click',
'.advads-conditions-authors-buttons .button',
function () {
$(this).remove();
}
);
// display input field to search for author.
$(document).on(
'click',
'.advads-conditions-authors-show-search',
function (e) {
e.preventDefault();
// display input field.
$(this)
.siblings('.advads-conditions-authors-search')
.show()
.focus();
// register autocomplete.
advadsRegisterAuthorAutocomplete(
$(this).siblings('.advads-conditions-authors-search')
);
$(this).next('br').show();
$(this).hide();
}
);
// author search box autocomplete.
function advadsRegisterAuthorAutocomplete(self) {
self.autocomplete({
classes: {
'ui-autocomplete': 'advads-ui-autocomplete',
},
source(request, callback) {
advadsAuthorSearch(self, callback);
},
minLength: 1,
select(event, ui) {
// append new line with input fields.
$(
'<label class="button advads-button advads-ui-state-active"><span class="advads-button-text">' +
ui.item.label +
'<input type="hidden" name="' +
self.data('inputName') +
'" value="' +
ui.item.value +
'"></span></label>'
).appendTo(self.siblings('.advads-conditions-authors-buttons'));
},
close() {
self.val('');
},
});
}
// display input field to search for post, page, etc.
$(document).on(
'click',
'.advads-conditions-postids-show-search',
function (e) {
e.preventDefault();
// display input field.
$(this)
.next()
.find('.advads-display-conditions-individual-post')
.show();
//$( '.advads-conditions-postids-search-line .description' ).hide();
$(this).hide();
}
);
// register autocomplete to display condition individual posts.
// eslint-disable-next-line no-unused-vars
$(document).on(
'focus',
'.advads-display-conditions-individual-post',
// eslint-disable-next-line no-unused-vars
function (e) {
const self = this;
if (!$(this).data('autocomplete')) {
// If the autocomplete wasn't called yet:
$(this)
.autocomplete({
classes: {
'ui-autocomplete': 'advads-ui-autocomplete',
},
source(request, callback) {
const searchParam = request.term;
advads_post_search(searchParam, callback);
},
minLength: 1,
select(event, ui) {
// append new line with input fields
const newline = $(
`<label class="button advads-button advads-ui-state-active"><span class="advads-button-text">${ui.item.label}</span></label>`
);
$(
`<input type="hidden" name="${self.dataset.fieldName}[value][]" value="${ui.item.value}"/>`
).appendTo(newline);
newline.insertBefore(
$(self).parent(
'.advads-conditions-postids-search-line'
)
);
},
// eslint-disable-next-line no-unused-vars
close(event, ui) {
$(self).val('');
},
})
.autocomplete()
.data('ui-autocomplete')._renderItem = function (ul, item) {
ul.addClass(
'advads-conditions-postids-autocomplete-suggestions'
);
return $('<li></li>')
.append(
"<span class='left'>" +
item.label +
"</span>&nbsp;<span class='right'>" +
item.info +
'</span>'
)
.appendTo(ul);
};
}
}
);
// remove individual posts from the display conditions post list.
$(document).on(
'click',
'.advads-conditions-postid-buttons .button',
// eslint-disable-next-line no-unused-vars
function (e) {
$(this).remove();
}
);
// display/hide error message if no option was selected
// is also called on every click.
function advads_display_condition_option_not_selected() {
$('.advads-conditions-not-selected').each(function () {
if ($(this).siblings('input:checked').length) {
$(this).hide();
} else {
$(this).show();
}
});
}
advads_display_condition_option_not_selected();
// update error messages when an item is clicked.
$(document).on(
'click',
'.advads-conditions-terms-buttons input[type="checkbox"], .advads-conditions-single input[type="checkbox"]',
function () {
// needs a slight delay until the buttons are updated.
window.setTimeout(
advads_display_condition_option_not_selected,
200
);
}
);
// activate and toggle conditions connector option.
$('.advads-conditions-connector input').advads_button();
// dynamically change label.
jQuery(document).on(
'click',
'.advads-conditions-connector input',
function () {
if (jQuery(this).is(':checked')) {
jQuery(this)
.next('label')
.find('span')
.html(advadstxt.condition_or);
jQuery(this)
.parents('.advads-conditions-connector')
.addClass('advads-conditions-connector-or')
.removeClass('advads-conditions-connector-and');
} else {
jQuery(this)
.next('label')
.find('span')
.html(advadstxt.condition_and);
jQuery(this)
.parents('.advads-conditions-connector')
.addClass('advads-conditions-connector-and')
.removeClass('advads-conditions-connector-or');
}
}
);
// remove a line with a display or visitor condition.
$(document).on('click', '.advads-conditions-remove', function () {
const tr = $(this).parents('.advads-conditions-table tr');
const table = $(this).closest('.advads-conditions-table');
tr.prev('tr').remove();
tr.remove();
if (table.find('tr').length === 0) {
const fieldset = table.next('fieldset');
table.after(
'<input type="hidden" name="' +
fieldset.data('condition-form-name') +
'[0][type]" value="unknown">'
);
}
});
});
/**
* Callback for term search autocomplete
*
* @param {type} search term
* @param field
* @param {type} callback
* @return {obj} json object with labels and values
*/
function advads_term_search(field, callback) {
// return ['post', 'poster'];
const query = {
action: 'advads-terms-search',
nonce: advadsglobal.ajax_nonce,
};
query.search = field.val();
query.tax = field.data('tagName');
let querying = true;
const results = {};
jQuery.post(
ajaxurl,
query,
function (r) {
querying = false;
const results = [];
if (r) {
r.map(function (element, index) {
results[index] = {
value: element.term_id,
label: element.name,
};
});
}
callback(results);
},
'json'
);
}
/**
* Callback for author search autocomplete
*
* @param {string} search author
* @param {HTMLInputElement} field html input field
* @param {Function} callback Callback function
* @return {Object} JSON object with labels and values
*/
function advadsAuthorSearch(field, callback) {
const query = {
action: 'advads-authors-search',
nonce: advadsglobal.ajax_nonce,
};
query.search = field.val();
let querying = true;
const results = [];
// eslint-disable-next-line no-undef
jQuery.post(
// eslint-disable-next-line no-undef
ajaxurl,
query,
function (r) {
querying = false;
if (r) {
r.map(function (element, index) {
results[index] = {
value: element.data.ID,
label: element.data.display_name,
};
});
}
callback(results);
},
'json'
);
}
/**
* Callback for post search autocomplete
*
* @param {str} searchParam
* @param {type} callback
* @return {obj} json object with labels and values
*/
function advads_post_search(searchParam, callback) {
// return ['post', 'poster'];
const query = {
action: 'advads-post-search',
_ajax_linking_nonce: jQuery('#_ajax_linking_nonce').val(),
search: searchParam,
nonce: advadsglobal.ajax_nonce,
};
let querying = true;
const results = {};
jQuery.post(
ajaxurl,
query,
function (r) {
querying = false;
const results = [];
if (r) {
// eslint-disable-next-line array-callback-return
r.map(function (element, index) {
results[index] = {
label: element.title,
value: element.ID,
info: element.info,
};
});
}
callback(results);
},
'json'
);
}

View File

@@ -0,0 +1,175 @@
// phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact -- PHPCS can't handle es5 short functions
const modal = element => {
let targetForm;
/**
* Remove the pound sign from the location hash.
*
* @return {string}
*/
const getId = () => window.location.hash.replace( '#', '' );
const showModal = () => {
element.showModal();
element.dispatchEvent( new CustomEvent( 'advads-modal-opened' ) );
// Attach the termination object to the dialog node to allow other's code to plug in.
element.advadsTermination = new Advads_Termination( element );
if ( targetForm ) {
element.advadsTermination.collectValues();
}
};
/**
* If the current hash matches the modal id attribute, open it.
*/
const showIfHashMatches = () => {
if ( getId() === element.id ) {
showModal();
}
};
// Check whether to open modal on page load.
showIfHashMatches();
/**
* Listen to the hashchange event, to check if the current modal needs to be opened.
*/
window.addEventListener( 'hashchange', () => {
showIfHashMatches();
if ( getId() !== 'close' ) {
return;
}
if ( ! targetForm || element.advadsTermination.terminationNotice( true ) ) {
element.close();
}
} );
/**
* Attach a click listener to all links referencing this modal and prevent their default action.
* By changing the hash on every click, we also create a history entry.
*/
document.querySelectorAll( 'a[href$="#' + element.id + '"]' ).forEach( link => {
link.addEventListener( 'click', e => {
e.preventDefault();
showModal();
} );
} );
/**
* On the cancel event, check for termination notice and fire a custom event.
*/
element.addEventListener( 'cancel', event => {
event.preventDefault();
if ( ! targetForm ) {
element.close();
return;
}
if ( element.advadsTermination.terminationNotice( true ) ) {
element.close();
element.advadsTermination.observers.disconnect();
document.dispatchEvent( new CustomEvent( 'advads-modal-canceled', {
detail: {
modal_id: element.id
}
} ) );
}
} );
/**
* On the close event, i.e., a form got submit, empty the hash to prevent form from reopening.
*/
element.addEventListener( 'close', event => {
if ( getId() === element.id ) {
window.location.hash = '';
}
} );
// try if there is a form inside the modal, otherwise continue in catch.
targetForm = element.querySelector( 'form' );
if ( targetForm === null ) {
try {
targetForm = element.querySelector( 'button.advads-modal-close-action' ).form;
} catch ( e ) {
}
}
if ( targetForm ) {
/**
* Listen for the keydown event in all inputs.
* If the enter key is pressed and the modal has a form, submit it, else do nothing.
*/
element.querySelectorAll( 'input' ).forEach( input => {
input.addEventListener( 'keydown', e => {
if ( e.key !== 'Enter' ) {
return;
}
if ( targetForm.reportValidity() ) {
let submitForm = true;
if ( 'function' === typeof window[element.closeValidation.function] && ! window[element.closeValidation.function]( element.closeValidation.modal_id ) ) {
e.preventDefault();
return;
}
/**
* Allow other code to prevent the form submission (and send it using an AJAX call for instance).
*/
submitForm = wp.hooks.applyFilters( 'advanced-ads-submit-modal-form', true, targetForm, element.advadsTermination.initialFormValues, element.advadsTermination.changedFormValues );
if ( ! submitForm ) {
e.preventDefault();
return;
}
targetForm.submit();
}
// if there are inputs, but there is no form associated with them, do nothing.
e.preventDefault();
} );
} );
targetForm.addEventListener( 'submit', () => {
window.location.hash = '';
} );
}
/**
* On the cancel buttons, check termination notice and close the modal.
*/
element.querySelectorAll( '.advads-modal-close, .advads-modal-close-background' ).forEach( button => {
button.addEventListener( 'click', e => {
e.preventDefault();
element.dispatchEvent( new Event( 'cancel' ) );
} );
} );
try {
/**
* If the save button is not a `<button>` element. Close the form without changing the hash.
*/
element.querySelector( 'a.advads-modal-close-action' ).addEventListener( 'click', e => {
e.preventDefault();
element.close();
} );
} catch ( e ) {
}
};
window.addEventListener( 'DOMContentLoaded', () => {
try {
if ( typeof document.querySelector( '.advads-modal[id^=modal-]' ).showModal !== 'function' ) {
return;
}
} catch ( e ) {
return;
}
[...document.getElementsByClassName( 'advads-modal' )].forEach( modal );
} );

View File

@@ -0,0 +1,57 @@
jQuery(document).ready(function ($) {
function getCellValue(row, sortby, index) {
const $td = $(row).find('td');
if ('weight' === sortby) {
return parseInt($td.eq(index).find('select').val()) || 0;
}
if ('ad' === sortby) {
return $td.eq(index).find('a').text().trim();
}
return $td.eq(index).text().trim();
}
function sortAds(sortby, isAscending, table) {
const colIndex = $(table).find(`th[data-sortby=${sortby}]`).index();
const tbody = $(table).find('tbody');
const rows = tbody.find('tr').toArray();
rows.sort(function (a, b) {
const aValue = getCellValue(a, sortby, colIndex);
const bValue = getCellValue(b, sortby, colIndex);
if (isNaN(aValue) || isNaN(bValue)) {
return isAscending
? aValue.localeCompare(bValue)
: bValue.localeCompare(aValue);
}
return isAscending ? aValue - bValue : bValue - aValue;
});
tbody.append(rows);
$(table)
.find('th.group-sort')
.removeClass('asc desc')
.eq(colIndex)
.addClass(isAscending ? 'asc' : 'desc');
}
$('.advads-group-ads').each(function () {
const $this = $(this);
// eslint-disable-next-line prefer-const
let sortStates = {
ad: true,
status: true,
weight: true,
};
$this.find('th.group-sort').on('click', function () {
const sortby = $(this).data('sortby');
sortAds(sortby, sortStates[sortby], this.closest('table'));
sortStates[sortby] = !sortStates[sortby];
});
});
});

View File

@@ -0,0 +1,274 @@
// phpcs:disable Generic.WhiteSpace.ScopeIndent.IncorrectExact -- PHPCS can't handle es5 short functions
function Advads_Termination( element ) {
/**
* Function to reset the changed nodes to default values.
*
* @constructor
*/
function FormValues() {
this.addedNodes = [];
this.removedNodes = [];
};
this.initialFormValues = new FormValues();
this.changedFormValues = new FormValues();
const blocklist = [
'active_post_lock'
];
this.observers = {
list: [],
push: item => {
this.observers.list.push( item );
},
disconnect: () => {
this.observers.list.forEach( observer => {
observer.disconnect();
} );
this.observers.list = [];
}
};
/**
* Set an initial form value.
* Can be used e.g. when a field is updated after an AJAX call.
*
* @param {String} key The key of the value that should be changed in the initial form value array.
* @param {Node} input The input field node.
*
* @returns {void}
*/
this.setInitialValue = ( key, input ) => {
if ( ! input || ! input.value ) {
return;
}
this.initialFormValues[key] = input.value;
};
/**
* Collect input values.
* Checkboxes are true/false, unless they are part of a group.
* Radio buttons have a boolean value on the saved value, only the checked one will be collected.
*
* @param {FormValues} object
* @param {Node} input
* @return {FormValues}
*/
const collectInputValue = function ( object, input ) {
/**
* Collect checkbox group values.
* If there are multiple checkboxes with the same `nome` attribute, collect all values for this group.
*
* @param {NodeList} group Iterable of inputs with the same `name` attribute.
* @return {FormValues}
*/
const collectCheckboxGroup = ( group ) => {
object[group[0].name] = [];
group.forEach( input => {
if ( input.checked ) {
object[input.name].push( input.value );
}
} );
return object;
};
if ( input.type === 'checkbox' ) {
const checkboxGroup = element.querySelectorAll( '[name="' + input.name + '"]' );
if ( checkboxGroup.length > 1 ) {
return collectCheckboxGroup( checkboxGroup, input );
}
object[input.name] = input.checked;
return object;
}
// if a radio button is not checked, don't collect it.
if ( input.type === 'radio' && ! input.checked ) {
return object;
}
object[input.name] = input.value;
return object;
};
/**
* Setup a mutationobserver to check for added and removed form fields.
* This especially applies to conditions.
*
* @type {MutationObserver}
*/
const addedRemovedObserver = new MutationObserver( mutations => {
for ( const mutation of mutations ) {
for ( const removedNode of mutation.removedNodes ) {
const nodes = document.createTreeWalker( removedNode, NodeFilter.SHOW_ELEMENT );
while ( nodes.nextNode() ) {
if ( nodes.currentNode.tagName === 'INPUT' || nodes.currentNode.tagName === 'SELECT' ) {
const index = this.changedFormValues.addedNodes.indexOf( nodes.currentNode.name );
if ( index > - 1 ) {
this.changedFormValues.addedNodes.splice( index, 1 );
} else {
this.changedFormValues.removedNodes.push( nodes.currentNode.name );
}
}
}
}
for ( const addedNode of mutation.addedNodes ) {
if ( addedNode.nodeType === Node.TEXT_NODE ) {
continue;
}
const nodes = document.createTreeWalker( addedNode, NodeFilter.SHOW_ELEMENT );
while ( nodes.nextNode() ) {
if ( nodes.currentNode.tagName === 'INPUT' || nodes.currentNode.tagName === 'SELECT' ) {
if ( nodes.currentNode.name === '' ) {
continue;
}
this.changedFormValues.addedNodes.push( nodes.currentNode.name );
}
}
}
}
} );
// attach the mutation observer to the passed element.
addedRemovedObserver.observe( element, {childList: true, subtree: true} );
this.observers.push( addedRemovedObserver );
/**
* Check if there are inputs that have been changed and if their value is different.
*
* @param {Object} reference The initial values when the modal loaded, indexed by name attribute.
* @param {Object} changed The input values that were changed, indexed by name.
*
* @return {boolean}
*/
this.hasChanged = ( reference, changed ) => {
for ( const name in changed ) {
if ( ! reference.hasOwnProperty( name ) || reference[name].toString() !== changed[name].toString() ) {
return true;
}
}
return false;
};
/**
* If the modal is associated with a form and any values have changed, ask for confirmation to navigate away.
* Returns true if the user agrees with termination, false otherwise.
*
* @param {boolean} reload Whether to reload the page on added and removed nodes (needed for the modal). Default false.
*
* @return {boolean}
*/
this.terminationNotice = ( reload = false ) => {
if ( ! this.hasChanged( this.initialFormValues, this.changedFormValues ) ) {
return true;
}
// ask user for confirmation.
if ( window.confirm( window.advadstxt.confirmation ) ) {
// if we have added or removed nodes, we might need to reload the page.
if ( this.changedFormValues.addedNodes.length || this.changedFormValues.removedNodes.length ) {
if ( reload ) {
window.location.reload();
}
return true;
}
// otherwise, we'll replace the values with the previous values.
for ( const name in this.changedFormValues ) {
const input = element.querySelector( '[name="' + name + '"]' );
if ( input === null ) {
continue;
}
if ( input.type === 'checkbox' ) {
input.checked = this.initialFormValues[name];
} else if ( input.type === 'radio' ) {
let value = (this.initialFormValues[name] !== null && this.initialFormValues[name] !== undefined) ? this.initialFormValues[name] : input.value;
element.querySelector( '[name="' + name + '"][value="' + value + '"]' ).checked = true;
} else {
input.value = this.initialFormValues[name];
}
}
return true;
}
return false;
};
/**
* Set the initial values to the current ones, then reset the changed form values
*/
this.resetInitialValues = () => {
if ( this.changedFormValues.addedNodes.length ) {
for ( const name in this.changedFormValues.addedNodes ) {
this.initialFormValues[name] = this.changedFormValues.addedNodes[name];
}
}
if ( this.changedFormValues.removedNodes.length ) {
for ( const name in this.changedFormValues.removedNodes ) {
if ( this.initialFormValues[name] !== undefined ) {
delete ( this.initialFormValues[name] );
}
}
}
for ( const name in this.changedFormValues ) {
if ( 'removedNodes' === name || 'addedNodes' === name ) {
continue;
}
if ( this.initialFormValues[name] !== undefined ) {
this.initialFormValues[name] = this.changedFormValues[name];
}
}
this.changedFormValues = new FormValues();
};
/**
* Collect inputs in this modal and save their initial and changed values (if any).
*/
this.collectValues = () => {
const isDialog = element.tagName === 'DIALOG';
element.querySelectorAll( 'input, select, textarea' ).forEach( input => {
if ( ! input.name.length || blocklist.includes( input.id ) || blocklist.includes( input.name ) ) {
return;
}
// if the element itself is not a dialog but the input is within a dialog, ignore it. This accounts for split forms, e.g. the placements page where some inputs are hidden in a modal dialog.
if ( ! isDialog && input.closest( 'dialog' ) ) {
return;
}
this.initialFormValues = collectInputValue( this.initialFormValues, input );
// if the input is `hidden` no change event gets triggered. Use MutationObservers to check for changes in the value attribute.
if ( input.type === 'hidden' ) {
const hiddenObserver = new MutationObserver( function ( mutations, observer ) {
mutations.forEach( mutation => {
if ( mutation.attributeName === 'value' ) {
mutation.target.dispatchEvent( new Event( 'input' ) );
}
} );
} );
hiddenObserver.observe( element, {
attributes: true,
subtree: true
} );
this.observers.push( hiddenObserver );
}
input.addEventListener( 'input', event => {
this.changedFormValues = collectInputValue( this.changedFormValues, input );
} );
} );
};
};

View File

@@ -0,0 +1,150 @@
(function ( $ ) {
/**
* Button.
*/
$.fn.advads_button = function() {
var $buttonset = jQuery( this );
var $ancestor = $buttonset.parent();
$buttonset.each( function() {
$this = jQuery( this );
if ( $this.data( 'advads_button' ) ) {
return true;
}
$this.data( 'advads_button', true );
var $button = jQuery( this );
var $label = jQuery( 'label[for="' + $button.attr( 'id' ) + '"]', $ancestor );
var type = $button.attr( 'type' );
$button.addClass( 'advads-accessible' );
$label.addClass( 'advads-button' );
$label.wrapInner( '<span class="advads-button-text"></span>' );
if ( $button.is( ':checked' ) ) {
$label.addClass( 'advads-ui-state-active' );
}
$button.on('change', function() {
var $changed = jQuery( this );
var $label = jQuery( 'label[for="' + $changed.attr( 'id' ) + '"]', $ancestor );
if ( type === 'radio' ) {
$ancestor.find( 'label' ).removeClass( 'advads-ui-state-active' );
}
if ( $changed.is( ':checked' ) ) {
$label.addClass( 'advads-ui-state-active' );
} else {
$label.removeClass( 'advads-ui-state-active' );
}
} );
} );
};
/**
* Buttonset.
*/
$.fn.advads_buttonset = function() {
var $that = jQuery( this );
$that.each( function() {
$buttonset = jQuery( this );
if ( $buttonset.data( 'advads_buttonset' ) ) {
return true;
}
$buttonset.data( 'advads_buttonset', true );
var items = 'input[type=checkbox], input[type=radio]';
var $all_buttons = $buttonset.find( items );
if ( ! $all_buttons.length ) {
return;
}
// Show selected checkboxes first.
if ( jQuery.escapeSelector ) {
$items = jQuery();
$all_buttons.filter( ':checked' ).each( function() {
$items = $items.add( $buttonset.find( 'label[for="' + jQuery.escapeSelector( this.id ) + '"]' ) );
$items = $items.add( this );
} );
$items.prependTo( $buttonset );
}
$buttonset.addClass( 'advads-buttonset' );
$all_buttons.advads_button();
} );
};
/**
* Tooltip.
*
* @param {Function} options.content A function that returns the content.
*/
$.fn.advads_tooltip = function( options ) {
var tooltip;
var tooltip_target;
if ( ! options.content ) {
return this;
}
function open( event ) {
var $target = jQuery( event.currentTarget );
// check if the correct tooltip is already open.
if ( tooltip && $target.is( tooltip_target ) ) {
return;
}
if ( tooltip ) {
tooltip.remove();
tooltip = null;
tooltip_target = null;
}
if ( event.type === 'mouseover' ) {
jQuery( $target ).on( 'mouseleave', close );
}
if ( event.type === 'focusin' ) {
jQuery( $target ).on( 'focusout', close );
}
var content = options.content.call( $target )
if ( content ) {
tooltip = $( '<div>' ).addClass( 'advads-tooltip' );
const parent = typeof options.parent === 'function' ? options.parent.call( this, $target ) : 'body';
$( '<div>' ).addClass( 'advads-tooltip-content' ).appendTo( tooltip );
tooltip.appendTo( parent );
tooltip.find( '.advads-tooltip-content' ).html( content );
position = $target.offset();
position.top += $target.outerHeight() + 15;
tooltip.offset( position );
tooltip_target = $target;
tooltip.show();
}
}
function close( event ) {
if ( tooltip ) {
tooltip.remove();
tooltip = null;
tooltip_target = null;
}
};
this.each( function() {
$this = jQuery( this );
if ( $this.data( 'advads_tooltip' ) ) {
return true;
}
$this.data( 'advads_tooltip', true );
$this.on( 'mouseover focusin', open );
} );
};
} )( jQuery );

View File

@@ -0,0 +1,213 @@
/* eslint-disable camelcase */
const advads_wizard = {
box_order: [
// selectors of elements in the wizard in the correct order
'#post-body-content, #ad-types-box', // show title and type together
'#ad-parameters-box',
'#ad-targeting-box', // display and visitor conditions
],
current_box: '#post-body-content, #ad-types-box', // current active box
one_column: false, // whether the edit screen is in one-column mode
status: false, // what is the current status? true if running, else false
init() {
// status can be "start" to start wizard or nothing to not start it
const _this = this;
jQuery('#advads-wizard-controls-next').on('click', function () {
_this.next();
});
jQuery('#advads-wizard-controls-prev').on('click', function () {
_this.prev();
});
jQuery('#advads-wizard-controls-save').on('click', function (e) {
e.preventDefault();
jQuery('#publish').trigger('click');
}); // save ad
jQuery('#advads-wizard-display-conditions-show').on(
'click',
function () {
_this.show_conditions('#ad-targeting-box');
}
);
jQuery('#advads-wizard-visitor-conditions-show').on(
'click',
function () {
_this.show_conditions('#ad-targeting-box');
}
);
jQuery('.advads-show-in-wizard').hide();
jQuery('#advads-start-wizard').on('click', function () {
_this.start();
});
// end wizard when the button was clicked
jQuery('.advads-stop-wizard').on('click', function () {
_this.close();
});
// jump to next box when ad type is selected
jQuery('#advanced-ad-type input').on('change', function () {
_this.next();
});
},
show_current_box() {
jQuery(this.current_box).removeClass('advads-hide');
},
start() {
// do stuff when wizard is started
if (!this.is_form_valid()) {
return;
}
// show page in 1-column stype
this.status = true;
if (jQuery('#post-body').hasClass('columns-1')) {
this.one_column = true;
} else {
jQuery('#post-body').addClass('columns-1').removeClass('columns-2');
}
// hide all boxes, messages and the headline by adding a hide css class
jQuery(
'#post-body-content, .postbox-container .postbox, h1 ~ div:not(.advads-admin-notice):not(#message.updated), h1'
).addClass('advads-hide');
// display first box
this.show_current_box();
// display close button and controls
jQuery('#advads-stop-wizard, #advads-wizard-controls').removeClass(
'hidden'
);
this.update_nav();
// initially hide some elemente
jQuery('#advads-ad-description').addClass('advads-hide'); // ad description
jQuery('#advads-ad-info').addClass('advads-hide'); // shortcode and php function info
// hide all elements with 'advads-hide-for-wizard' class
jQuery('.advads-hide-in-wizard').hide();
jQuery('.advads-show-in-wizard').show();
jQuery('#advads-start-wizard').hide();
// remove close-class from ad type box
jQuery('#ad-types-box').removeClass('closed');
this.save_hide_wizard(false);
},
close() {
// close the wizard by showing all elements again
this.status = false;
jQuery('.advads-hide').removeClass('advads-hide');
jQuery('#advads-stop-wizard, #advads-wizard-controls').addClass(
'hidden'
);
if (this.one_column !== true) {
jQuery('#post-body').addClass('columns-2').removeClass('columns-1');
}
// reset current box
this.current_box = this.box_order[0];
jQuery('#advads-wizard-welcome').remove(); // close wizard welcome message
// show all elements with 'advads-hide-for-wizard' class
jQuery('.advads-hide-in-wizard').show();
jQuery('.advads-show-in-wizard').hide();
jQuery('#advads-start-wizard').show();
this.save_hide_wizard(true);
},
update_nav() {
// update navigation, display only valid buttons
// display all buttons
jQuery('#advads-wizard-controls button').removeClass('hidden');
// hide next button if there is no next widget
const i = this.box_order.indexOf(this.current_box);
if (i === this.box_order.length - 1) {
jQuery('#advads-wizard-controls-next').addClass('hidden');
}
if (i === 0) {
jQuery('#advads-wizard-controls-prev').addClass('hidden');
}
// hide save button for first boxes
if (i <= 1) {
jQuery('#advads-wizard-controls-save').addClass('hidden');
} else {
jQuery('#advads-wizard-controls-save').removeClass('hidden');
}
},
/**
* Check the form just before some of its fields become hidden.
*/
is_form_valid() {
const form = jQuery('form#post')[0];
if (form.checkValidity && form.reportValidity) {
if (!form.checkValidity()) {
// Highlight invalid fields.
form.reportValidity();
return false;
}
return true;
}
// Disable validation so that hidden invalid fields do not prevent the form from being sent.
form.setAttribute('novalidate', true);
return true;
},
next() {
// show next box
if (!this.is_form_valid()) {
return;
}
if (!this.status) {
return;
}
// get index of current item in box-array
const i = this.box_order.indexOf(this.current_box);
// check if there is a next index
if (this.box_order[i + 1] === undefined) {
return;
}
// hide current element
jQuery(this.current_box).addClass('advads-hide');
// load next element into current
this.current_box = this.box_order[i + 1];
this.show_current_box();
this.update_nav();
},
prev() {
// show previous box
if (!this.is_form_valid()) {
return;
}
// get index of current item in box-array
const i = this.box_order.indexOf(this.current_box);
// check if there is a previous index
if (this.box_order[i - 1] === undefined) {
return;
}
// hide current element
jQuery(this.current_box).addClass('advads-hide');
// load next element into current
this.current_box = this.box_order[i - 1];
this.show_current_box();
this.update_nav();
},
save_hide_wizard(hideWizard) {
// update wizard state (started by default or not?)
jQuery.ajax({
type: 'POST',
url: ajaxurl,
data: {
action: 'advads-save-hide-wizard-state',
hideWizard,
nonce: advadsglobal.ajax_nonce,
},
});
},
show_conditions(box) {
// show the conditions options in display and visitor conditions
jQuery(box).find('.advads-show-in-wizard').hide();
jQuery(box).find('.advads-hide-in-wizard').show();
},
};
jQuery(document).ready(function () {
advads_wizard.init();
});

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<advads-export>
<ads type="array">
<item key="0" type="array">
<ID type="string">1</ID>
<post_content type="string">
<![CDATA[<div style="width: 100%; height: 90px; background: #15A2E1; color: #fff; line-height: 90px; text-align: center; ">Example Ad #1 (only visible for logged-in visitors)</div>]]></post_content>
<post_title type="string">Example Ad #1 (only for logged-in visitors)</post_title>
<post_status type="string">publish</post_status>
<meta_input type="array">
<advanced_ads_ad_options type="array">
<visitor type="array"/>
<visitors type="array">
<item key="0" type="array">
<type type="string">loggedin</type>
<operator type="string">is</operator>
</item>
</visitors>
<output type="array">
<allow_php type="string">0</allow_php>
</output>
<type type="string">plain</type>
<width type="numeric">0</width>
<height type="numeric">0</height>
</advanced_ads_ad_options>
</meta_input>
</item>
<item key="1" type="array">
<ID type="string">2</ID>
<post_content type="string">
<![CDATA[<div style="width: 100%; height: 90px; background: #04B404; color: #fff; line-height: 90px; text-align: center; ">Example Ad #2 (only visible for logged-in visitors)</div>]]></post_content>
<post_title type="string">Example Ad #2 (only for logged-in visitors)</post_title>
<post_status type="string">publish</post_status>
<meta_input type="array">
<advanced_ads_ad_options type="array">
<visitor type="array"/>
<visitors type="array">
<item key="0" type="array">
<type type="string">loggedin</type>
<operator type="string">is</operator>
</item>
</visitors>
<output type="array">
<allow_php type="string">0</allow_php>
</output>
<type type="string">plain</type>
<width type="numeric">0</width>
<height type="numeric">0</height>
</advanced_ads_ad_options>
</meta_input>
</item>
</ads>
<placements type="array">
<item key="0" type="array">
<type type="string">post_top</type>
<name type="string">Before Content Placement</name>
<item type="string">ad_1</item>
<key type="string">before-content-placement</key>
</item>
<item key="1" type="array">
<type type="string">post_content</type>
<name type="string">Content Placement after 3rd Paragraph</name>
<item type="string">ad_2</item>
<options type="array">
<position type="string">after</position>
<index type="numeric">3</index>
<tag type="string">p</tag>
<ad_label type="string">default</ad_label>
<placement_position type="string"/>
</options>
<key type="string">content-placement-after-3rd-paragraph</key>
</item>
</placements>
</advads-export>