first commit
This commit is contained in:
182
admin-kalsport/themes/new-theme/js/app/utils/serp/index.js
Normal file
182
admin-kalsport/themes/new-theme/js/app/utils/serp/index.js
Normal file
@@ -0,0 +1,182 @@
|
||||
/**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*/
|
||||
import Vue from 'vue';
|
||||
import {EventEmitter} from '@components/event-emitter';
|
||||
import serp from './serp.vue';
|
||||
|
||||
const {$} = window;
|
||||
|
||||
/**
|
||||
* Vue component displaying a search page result, Google style.
|
||||
* Requires a tag with the id "#serp-app" to be present in the DOM to run it.
|
||||
* The component is automatically updated by watching several inputs.
|
||||
* Set the proper class to link a input to a part of the panel.
|
||||
*/
|
||||
class SerpApp {
|
||||
constructor(selectors, url) {
|
||||
// If the selector cannot be found, we do not load the Vue app
|
||||
if ($(selectors.container).length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.originalUrl = url;
|
||||
this.useMultiLang = selectors.multiLanguageInput !== undefined || selectors.multiLanguageField !== undefined;
|
||||
|
||||
if (this.useMultiLang) {
|
||||
const possibleSelectors = [];
|
||||
|
||||
if (selectors.multiLanguageInput) {
|
||||
possibleSelectors.push(selectors.multiLanguageInput);
|
||||
}
|
||||
if (selectors.multiLanguageField) {
|
||||
possibleSelectors.push(selectors.multiLanguageField);
|
||||
}
|
||||
this.multiLangSelector = possibleSelectors.join(',');
|
||||
this.attachMultiLangEvents();
|
||||
}
|
||||
|
||||
this.data = {
|
||||
url,
|
||||
title: '',
|
||||
description: '',
|
||||
};
|
||||
|
||||
this.vm = new Vue({
|
||||
el: selectors.container,
|
||||
template: '<serp ref="serp" :url="url" :title="title" :description="description" />',
|
||||
components: {serp},
|
||||
data: this.data,
|
||||
});
|
||||
|
||||
this.initializeSelectors(selectors);
|
||||
this.attachInputEvents();
|
||||
}
|
||||
|
||||
attachMultiLangEvents(itemSelector) {
|
||||
$('body').on(
|
||||
'click',
|
||||
itemSelector,
|
||||
() => {
|
||||
this.checkTitle();
|
||||
this.checkDesc();
|
||||
this.checkUrl();
|
||||
},
|
||||
);
|
||||
|
||||
EventEmitter.on('languageSelected', () => {
|
||||
this.checkTitle();
|
||||
this.checkDesc();
|
||||
this.checkUrl();
|
||||
});
|
||||
}
|
||||
|
||||
initializeSelectors(selectors) {
|
||||
this.defaultTitle = $(selectors.defaultTitle);
|
||||
this.watchedTitle = $(selectors.watchedTitle);
|
||||
this.defaultDescription = $(selectors.defaultDescription);
|
||||
this.watchedDescription = $(selectors.watchedDescription);
|
||||
this.watchedMetaUrl = $(selectors.watchedMetaUrl);
|
||||
}
|
||||
|
||||
attachInputEvents() {
|
||||
$(this.defaultTitle).on('keyup change', () => this.checkTitle());
|
||||
$(this.watchedTitle).on('keyup change', () => this.checkTitle());
|
||||
$(this.defaultDescription).on('keyup change', () => this.checkDesc());
|
||||
$(this.watchedDescription).on('keyup change', () => this.checkDesc());
|
||||
this.watchedMetaUrl.on('keyup change', () => this.checkUrl());
|
||||
|
||||
this.checkTitle();
|
||||
this.checkDesc();
|
||||
this.checkUrl();
|
||||
}
|
||||
|
||||
setTitle(title) {
|
||||
this.data.title = title;
|
||||
}
|
||||
|
||||
setDescription(description) {
|
||||
this.data.description = description;
|
||||
}
|
||||
|
||||
setUrl(rewrite) {
|
||||
// We replace two placeholders because there was a typo in the initial one ('friendy' instead of 'friendly')
|
||||
this.data.url = this.originalUrl.replace(
|
||||
'{friendy-url}',
|
||||
rewrite,
|
||||
);
|
||||
this.data.url = this.data.url.replace(
|
||||
'{friendly-url}',
|
||||
rewrite,
|
||||
);
|
||||
}
|
||||
|
||||
checkTitle() {
|
||||
let {defaultTitle} = this;
|
||||
let {watchedTitle} = this;
|
||||
|
||||
if (this.useMultiLang) {
|
||||
watchedTitle = watchedTitle.closest(this.multiLangSelector).find('input');
|
||||
defaultTitle = defaultTitle.closest(this.multiLangSelector).find('input');
|
||||
}
|
||||
|
||||
const title1 = watchedTitle.length ? watchedTitle.val() : '';
|
||||
const title2 = defaultTitle.length ? defaultTitle.val() : '';
|
||||
|
||||
this.setTitle(title1 === '' ? title2 : title1);
|
||||
// Always check for url if title change
|
||||
this.checkUrl();
|
||||
}
|
||||
|
||||
checkDesc() {
|
||||
let {watchedDescription} = this;
|
||||
let {defaultDescription} = this;
|
||||
|
||||
if (this.useMultiLang) {
|
||||
watchedDescription = watchedDescription
|
||||
.closest(this.multiLangSelector)
|
||||
.find(this.watchedDescription.is('input') ? 'input' : 'textarea');
|
||||
defaultDescription = defaultDescription
|
||||
.closest(this.multiLangSelector)
|
||||
.find(this.defaultDescription.is('input') ? 'input' : 'textarea');
|
||||
}
|
||||
|
||||
const desc1 = watchedDescription.length ? watchedDescription.val().innerText || watchedDescription.val() : '';
|
||||
const desc2 = defaultDescription.length ? $(defaultDescription.val()).text() || defaultDescription.val() : '';
|
||||
|
||||
this.setDescription(desc1 === '' ? desc2 : desc1);
|
||||
}
|
||||
|
||||
checkUrl() {
|
||||
let {watchedMetaUrl} = this;
|
||||
|
||||
if (this.useMultiLang) {
|
||||
watchedMetaUrl = watchedMetaUrl.closest(this.multiLangSelector).find('input');
|
||||
}
|
||||
|
||||
this.setUrl(watchedMetaUrl.val());
|
||||
}
|
||||
}
|
||||
|
||||
export default SerpApp;
|
||||
151
admin-kalsport/themes/new-theme/js/app/utils/serp/serp.vue
Normal file
151
admin-kalsport/themes/new-theme/js/app/utils/serp/serp.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<!--**
|
||||
* Copyright since 2007 PrestaShop SA and Contributors
|
||||
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
|
||||
*
|
||||
* NOTICE OF LICENSE
|
||||
*
|
||||
* This source file is subject to the Open Software License (OSL 3.0)
|
||||
* that is bundled with this package in the file LICENSE.md.
|
||||
* It is also available through the world-wide-web at this URL:
|
||||
* https://opensource.org/licenses/OSL-3.0
|
||||
* If you did not receive a copy of the license and are unable to
|
||||
* obtain it through the world-wide-web, please send an email
|
||||
* to license@prestashop.com so we can send you a copy immediately.
|
||||
*
|
||||
* DISCLAIMER
|
||||
*
|
||||
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
|
||||
* versions in the future. If you wish to customize PrestaShop for your
|
||||
* needs please refer to https://devdocs.prestashop.com/ for more information.
|
||||
*
|
||||
* @author PrestaShop SA and Contributors <contact@prestashop.com>
|
||||
* @copyright Since 2007 PrestaShop SA and Contributors
|
||||
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
|
||||
*-->
|
||||
<template>
|
||||
<div id="serp">
|
||||
<div class="serp-preview">
|
||||
<div class="serp-title">
|
||||
{{ displayedTitle }}
|
||||
</div>
|
||||
<div class="serp-url">
|
||||
{{ url }}<span class="serp-arrow" />
|
||||
</div>
|
||||
<div class="serp-description">
|
||||
{{ displayedDescription }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Serp',
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
default: 'https://www.example.com/',
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
displayedTitle() {
|
||||
if (this.title.length > 70) {
|
||||
return `${this.title.substring(0, 70)}...`;
|
||||
}
|
||||
|
||||
return this.title;
|
||||
},
|
||||
displayedDescription() {
|
||||
if (this.description.length > 150) {
|
||||
return `${this.description.substring(0, 150)}...`;
|
||||
}
|
||||
|
||||
return this.description;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" type="text/scss" scoped>
|
||||
.serp-preview {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.12);
|
||||
background-color: #ffffff;
|
||||
border: solid 1px #e7e7e7;
|
||||
padding: 30px;
|
||||
max-width: 700px;
|
||||
|
||||
.serp-arrow {
|
||||
border-bottom-color: rgb(0, 102, 33);
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 0px;
|
||||
border-left-color: rgba(0, 0, 0, 0);
|
||||
border-left-style: solid;
|
||||
border-left-width: 4px;
|
||||
border-right-color: rgba(0, 0, 0, 0);
|
||||
border-right-style: solid;
|
||||
border-right-width: 4px;
|
||||
border-top-color: rgb(0, 102, 33);
|
||||
border-top-style: solid;
|
||||
border-top-width: 5px;
|
||||
color: rgb(128, 128, 128);
|
||||
cursor: default;
|
||||
font-family: arial, sans-serif;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
height: 0px;
|
||||
position: absolute;
|
||||
line-height: 27px;
|
||||
margin-left: 3px;
|
||||
margin-top: 6px;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
visibility: visible;
|
||||
white-space: nowrap;
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
.serp-title {
|
||||
color: #1A0DAB;
|
||||
cursor: pointer;
|
||||
font-family: arial, regular;
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
text-decoration: none;
|
||||
visibility: visible;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.serp-url {
|
||||
color: #006621;
|
||||
font-family: arial, regular;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.serp-description {
|
||||
color: #545454;
|
||||
font-family: arial, regular;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
text-align: left;
|
||||
visibility: visible;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user