В этой теме можно попросить сделать себе аватар, а также примерить одну из форумных плашек, фонов и описание в профиле. Также можно попросить прикрепить к плашке тему дневника или заполнить твинков.
• В какой форме можно попросить ссылки в плашку или в твинков?
В абсолютно свободной, все найдём-поймём.
• Это все плашки и фоны?
Они будут постоянно пополняться, не волнуйтесь.
• А можно ли попросить сделать свою плашку или фон?
Можно. Приносите исходник, сделаем. Размеры для фонов 240x330, размеры для плашек 180x40.
• А будут ли какие-то уникальные плашки и фоны?
Да, будут. За участие в конкурсах.
• Можно ли приносить гиф-исходники?
Можно для плашек, если они по весу не превышают 500МБ.
• А это обязательно?
Нет, конечно, все исключительно по желанию.
• Поставить только тут?
Вы можете ставить плашки и фоны самостоятельно через "Профиль" -> "Дополнительно".
[html]
<script>
// --------- СОСТОЯНИЕ DOM ------------
let iframeDomReady = document.readyState !== 'loading';
document.addEventListener('DOMContentLoaded', function () {
iframeDomReady = true;
initializeIframeForm();
});
// --------- ЭКРАНИРОВАНИЕ ------------
function escapeAttr(value) {
return String(value)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, '\'');
}
// --------- FILL BACKGROUNDS ------------
function labelBg(className, nameCategory, src) {
const safeSrc = escapeAttr(src);
return `
<label class="${className}">
<input
type="radio"
name="${nameCategory}"
id="${safeSrc}"
onchange="handleBgRadioChange()"
>
<img src="${safeSrc}" loading="lazy">
</label>
`;
}
function fillBgs(bgs) {
const container = document.getElementById('bgContainer');
if (!container) return;
container.innerHTML = (Array.isArray(bgs) ? bgs : [])
.map(function (bg) {
return labelBg('profileBgLabel', 'profileBg', bg);
})
.join('');
}
// --------- FILL STRIPES ------------
function labelStripe(className, nameCategory, src) {
const safeSrc = escapeAttr(src);
return `
<label class="${className}">
<input
type="radio"
name="${nameCategory}"
id="${safeSrc}"
onchange="handleStripeRadioChange()"
>
<img src="${safeSrc}" loading="lazy">
</label>
`;
}
function fillStripes(stripes) {
const container = document.getElementById('stripeContainer');
if (!container) return;
container.innerHTML = (Array.isArray(stripes) ? stripes : [])
.map(function (stripe) {
return labelStripe('profileStripeLabel', 'profileStripe', stripe);
})
.join('');
}
// --------- CUSTOM FIELD HANDLERS ------------
function handleStripeCustomInput() {
const customField = document.getElementById('stripeCustomLabel');
const customValue = customField ? customField.value : '';
if (customValue.trim()) {
document
.getElementsByName('profileStripe')
.forEach(function (radio) {
radio.checked = false;
});
}
updateProfilePreview();
}
function handleBgCustomInput() {
const customField = document.getElementById('bgCustomLabel');
const customValue = customField ? customField.value : '';
if (customValue.trim()) {
document
.getElementsByName('profileBg')
.forEach(function (radio) {
radio.checked = false;
});
}
updateProfilePreview();
}
function handleStripeRadioChange() {
const customField = document.getElementById('stripeCustomLabel');
if (customField) {
customField.value = '';
}
updateProfilePreview();
}
function handleBgRadioChange() {
const customField = document.getElementById('bgCustomLabel');
if (customField) {
customField.value = '';
}
updateProfilePreview();
}
// --------- USER DATA ------------
let userLatinName = '';
let userProfileUrl = '';
let userApplicationFormUrl = '';
let receivedStripes = [];
let receivedBackgrounds = [];
let profileDataReceived = false;
let profileRequestInterval = null;
function isAllowedParentOrigin(origin) {
return /^https?:\/\/oldshadows\.rusff\.me(?::\d+)?$/.test(origin);
}
function applyReceivedProfileData() {
if (!iframeDomReady) return;
fillStripes(receivedStripes);
fillBgs(receivedBackgrounds);
const urlField = document.getElementById('applicationFormUrl');
if (urlField && !urlField.value) {
urlField.value = userApplicationFormUrl;
}
updateProfilePreview();
}
function sendProfileRequest() {
window.parent.postMessage({
eventName: 'profileFillingRequest'
}, '*');
}
function startProfileRequesting() {
sendProfileRequest();
if (profileRequestInterval) {
clearInterval(profileRequestInterval);
}
profileRequestInterval = setInterval(function () {
if (profileDataReceived) {
clearInterval(profileRequestInterval);
profileRequestInterval = null;
return;
}
sendProfileRequest();
}, 1000);
}
// --------- COPY RESULTS ------------
function copyResults() {
let copyContent = '';
const cyrillicNameField = document.getElementById('cyrillicName');
const applicationFormUrlField = document.getElementById('applicationFormUrl');
const mainDescrField = document.getElementById('mainDescr');
const addDescrField = document.getElementById('addDescr');
const hrAddField = document.getElementById('hrAdd');
const cyrillicName = cyrillicNameField
? cyrillicNameField.value.trim()
: '';
if (cyrillicName) {
const applicationFormUrl =
applicationFormUrlField?.value.trim() ||
userApplicationFormUrl;
const profileDescrName = mainDescrField
? mainDescrField.value
: '';
let profileForm =
`<a href='${escapeAttr(applicationFormUrl)}'>${cyrillicName}</a>, ${profileDescrName}`;
const profileAdd = addDescrField
? addDescrField.value
: '';
const defaultAdditionalDescription =
`любое описание на ваш вкус <a href='ссылка на анкету персонажа'>имя на кириллице</a>`;
const profileAddNotFilled =
profileAdd.trim() === '' ||
profileAdd === defaultAdditionalDescription;
if (hrAddField?.checked) {
profileForm += '<hr>';
} else if (!profileAddNotFilled) {
profileForm += '<br>';
}
if (!profileAddNotFilled) {
profileForm += profileAdd;
}
copyContent +=
`Форма профиля:\n` +
`${String.fromCharCode(91)}code${String.fromCharCode(93)}` +
`${profileForm}` +
`${String.fromCharCode(91)}/code${String.fromCharCode(93)}\n\n`;
}
const stripeCustomField =
document.getElementById('stripeCustomLabel');
const stripeCustom = stripeCustomField
? stripeCustomField.value.trim()
: '';
let stripeForm = '';
if (stripeCustom) {
stripeForm = stripeCustom;
} else {
stripeForm = Array.from(
document.getElementsByName('profileStripe')
)
.filter(function (element) {
return element.checked;
})
.map(function (element) {
return element.id;
})
.join('');
}
if (stripeForm) {
copyContent +=
`Плашка:\n` +
`${String.fromCharCode(91)}img${String.fromCharCode(93)}` +
`${stripeForm}` +
`${String.fromCharCode(91)}/img${String.fromCharCode(93)}\n\n`;
}
const bgCustomField =
document.getElementById('bgCustomLabel');
const bgCustom = bgCustomField
? bgCustomField.value.trim()
: '';
let bgForm = '';
if (bgCustom) {
bgForm = bgCustom;
} else {
bgForm = Array.from(
document.getElementsByName('profileBg')
)
.filter(function (element) {
return element.checked;
})
.map(function (element) {
return element.id;
})
.join('');
}
if (bgForm) {
copyContent +=
`Фон:\n` +
`${String.fromCharCode(91)}img${String.fromCharCode(93)}` +
`${bgForm}` +
`${String.fromCharCode(91)}/img${String.fromCharCode(93)}\n\n`;
}
window.parent.postMessage({
eventName: 'profileCopyInfoRequest',
copyData: copyContent.trim()
}, '*');
}
// --------- POST USER PROFILE UPDATE ------------
function updateProfilePreview() {
if (!iframeDomReady) return;
const cyrillicNameField =
document.getElementById('cyrillicName');
const applicationFormUrlField =
document.getElementById('applicationFormUrl');
const mainDescrField =
document.getElementById('mainDescr');
const addDescrField =
document.getElementById('addDescr');
const hrAddField =
document.getElementById('hrAdd');
if (
!cyrillicNameField ||
!applicationFormUrlField ||
!mainDescrField ||
!addDescrField ||
!hrAddField
) {
return;
}
const cyrillicName =
cyrillicNameField.value.trim() ||
userLatinName;
const applicationFormUrl =
applicationFormUrlField.value.trim() ||
userApplicationFormUrl;
const profileDescrName =
mainDescrField.value;
let profileForm =
`<a href='${escapeAttr(applicationFormUrl)}'>${cyrillicName}</a>, ${profileDescrName}`;
const profileAdd =
addDescrField.value;
const defaultAdditionalDescription =
`любое описание на ваш вкус <a href='ссылка на анкету персонажа'>имя на кириллице</a>`;
const profileAddNotFilled =
profileAdd.trim() === '' ||
profileAdd === defaultAdditionalDescription;
if (hrAddField.checked) {
profileForm += '<hr>';
} else if (!profileAddNotFilled) {
profileForm += '<br>';
}
if (!profileAddNotFilled) {
profileForm += profileAdd;
}
const stripeCustomField =
document.getElementById('stripeCustomLabel');
const stripeCustom = stripeCustomField
? stripeCustomField.value.trim()
: '';
let stripeForm = '';
if (stripeCustom) {
stripeForm = stripeCustom;
} else {
stripeForm = Array.from(
document.getElementsByName('profileStripe')
)
.filter(function (element) {
return element.checked;
})
.map(function (element) {
return element.id;
})
.join('');
}
const bgCustomField =
document.getElementById('bgCustomLabel');
const bgCustom = bgCustomField
? bgCustomField.value.trim()
: '';
let bgForm = '';
if (bgCustom) {
bgForm = bgCustom;
} else {
bgForm = Array.from(
document.getElementsByName('profileBg')
)
.filter(function (element) {
return element.checked;
})
.map(function (element) {
return element.id;
})
.join('');
}
window.parent.postMessage({
eventName: 'profileDemo',
profileDescr: profileForm,
stripe: stripeForm,
background: bgForm
}, '*');
}
// --------- STYLE AND FONT ------------
let initialStyleReceived = false;
let receivedTheme = 'pink';
let styleRequestInterval = null;
let styleRequestTimeout = null;
function applyIframeStyle(style, theme) {
let appliedStyle = style;
if (style === 'system') {
appliedStyle = window
.matchMedia('(prefers-color-scheme: dark)')
.matches
? 'dark'
: 'light';
}
if (appliedStyle !== 'dark') {
appliedStyle = 'light';
}
if (typeof theme === 'string' && theme) {
receivedTheme = theme;
}
document.body.classList.remove('light', 'dark');
document.body.classList.add(appliedStyle);
document.body.classList.remove('pink', 'green');
document.body.classList.add(receivedTheme);
}
function applyIframeFont(data) {
const fontSize = Number(data.fontsize) || 12;
const fontFamily = data.fontfam || '0';
const allFontSize = Number(data.allFontSize) || 12;
document.documentElement.style.setProperty(
'--iframe-post-font-size',
fontSize + 'px'
);
document.documentElement.style.setProperty(
'--iframe-all-font-size',
allFontSize + 'px'
);
document
.querySelectorAll(
'.post-content p, ' +
'.post-content div, ' +
'.fillingForm, ' +
'.instructionBlock'
)
.forEach(function (element) {
element.style.fontSize = fontSize + 'px';
});
document
.querySelectorAll('.post-content p, .fillingForm')
.forEach(function (element) {
if (fontFamily !== '0') {
element.style.fontFamily = fontFamily;
} else {
element.style.removeProperty('font-family');
}
});
}
function requestParentStyle() {
window.parent.postMessage({
eventName: 'askStyle'
}, '*');
}
function stopStyleRequesting() {
if (styleRequestInterval) {
clearInterval(styleRequestInterval);
styleRequestInterval = null;
}
if (styleRequestTimeout) {
clearTimeout(styleRequestTimeout);
styleRequestTimeout = null;
}
}
function startStyleRequesting() {
stopStyleRequesting();
requestParentStyle();
styleRequestInterval = setInterval(function () {
if (initialStyleReceived) {
stopStyleRequesting();
return;
}
requestParentStyle();
}, 300);
styleRequestTimeout = setTimeout(function () {
stopStyleRequesting();
}, 10000);
}
// --------- MESSAGES FROM PARENT ------------
window.addEventListener('message', function (event) {
if (!isAllowedParentOrigin(event.origin)) return;
if (!event.data || typeof event.data !== 'object') return;
switch (event.data.eventName) {
case 'profileFillingResponce':
profileDataReceived = true;
if (profileRequestInterval) {
clearInterval(profileRequestInterval);
profileRequestInterval = null;
}
userLatinName =
event.data.userLatinName || '';
userProfileUrl =
event.data.userProfileUrl || '';
userApplicationFormUrl =
event.data.userApplicationFormUrl || '';
receivedStripes =
Array.isArray(event.data.stripes)
? event.data.stripes
: [];
receivedBackgrounds =
Array.isArray(event.data.backgrounds)
? event.data.backgrounds
: [];
applyReceivedProfileData();
break;
case 'styleChange':
initialStyleReceived = true;
applyIframeStyle(event.data.style, event.data.theme);
stopStyleRequesting();
break;
case 'fontChange':
applyIframeFont(event.data);
break;
}
});
// --------- INITIALIZATION ------------
function initializeIframeForm() {
const resultButton =
document.getElementById('instructionResult');
if (resultButton) {
resultButton.addEventListener('click', copyResults);
}
if (profileDataReceived) {
applyReceivedProfileData();
} else {
updateProfilePreview();
}
startProfileRequesting();
startStyleRequesting();
}
// Если скрипт выполнился после готовности DOM
if (iframeDomReady) {
initializeIframeForm();
}
</script>
<div class="fillingForm">
<label class="fillingCategoryRadio"><input type="radio" id="profileDescr" name="fillingCategoryRadio" checked /> <span>Описание в профиле</span></label>
<label class="fillingCategoryRadio"><input type="radio" id="profileStripe" name="fillingCategoryRadio" /> <span>Плашки</span></label>
<label class="fillingCategoryRadio"><input type="radio" id="profileBg" name="fillingCategoryRadio" /> <span>Фоны</span></label>
<div class="instructionBlock profileDescr">
<h2 class="instructionHeading">Описание в профиль</h2>
<label for="cyrillicName" class="labelDescr">Имя на кириллице:</label>
<input type="text" id="cyrillicName" name="cyrillicName" oninput="updateProfilePreview()">
<label for="applicationFormUrl" class="labelDescr">Ссылка на анкету:</label>
<input type="text" id="applicationFormUrl" name="applicationFormUrl" oninput="updateProfilePreview()">
<label for="mainDescr" class="labelDescr">Описание в профиль:</label>
<input type="text" id="mainDescr" name="mainDescr" value="возраст, раса, род деятельности" oninput="updateProfilePreview()">
<label for="hrAdd" class="hrAdd">
<input type="checkbox" id="hrAdd" name="hrAdd" onchange="updateProfilePreview()" />
<span>Добавить полосу между секциями</span>
</label>
<label for="addDescr" class="labelDescr">При желании можете добавить в профиль пару, красивую цитату, важного родственника, врага и тому подобное через это поле. Если не нужно, оставьте его пустым или не меняйте:</label>
<textarea id="addDescr" oninput="updateProfilePreview()" name="addDescr" rows="4">любое описание на ваш вкус <a href='ссылка на анкету персонажа'>имя на кириллице</a></textarea>
</div>
<div class="instructionBlock profileStripe">
<h2 class="instructionHeading">Плашки</h2>
<div id="stripeContainer"></div>
<div id="stripeCustom">
<label for="stripeCustomLabel" class="labelDescr">Своя плашка:</label>
<input type="text" id="stripeCustomLabel" name="stripeCustomLabel" oninput="handleStripeCustomInput()">
</div>
</div>
<div class="instructionBlock profileBg">
<h2 class="instructionHeading">Фоны</h2>
<div id="bgContainer"></div>
<div id="bgCustom">
<label for="bgCustomLabel" class="labelDescr">Свой фон:</label>
<input type="text" id="bgCustomLabel" name="bgCustomLabel" oninput="handleBgCustomInput()">
</div>
</div>
</div>
<div class="formButtons">
<input type="button" id="instructionResult" value="Скопировать код">
</div>
<style>
h2.instructionHeading {
font-size: 16px;
font-family: var(--font-accent);
font-weight: bold;
letter-spacing: 1px;
}
.labelDescr {
display: block;
margin: 9px 0px 1px 0px;
}
.instructionBlock {
text-align: left;
margin: 10px 0 !important;
padding: 14px 14px 12px 14px !important;
border: 1px solid var(--borders);
background: var(--beg300);
border-radius: 4px;
}
.instructionBlock input[type="text"] {
width: calc(100% - 10px);
}
.instructionBlock textarea {
width: calc(100% - 10px);
resize: vertical;
}
label.hrAdd {
margin: 10px 0 0 0;
display: block;
}
input#hrAdd {
accent-color: var(--text2);
}
.profileStripeLabel, .profileBgLabel {
margin: 5px 5px;
display: inline-block;
width: 180px;
border-radius: 5px;
padding: 5px;
background: rgb(255 255 255 / 17%);
}
.profileStripeLabel img, .profileBgLabel img { border-radius: 3px; }
.profileBgLabel img {
width: 180px;
height: 40px;
object-fit: cover;
object-position: top;
}
.profileStripeLabel input, .profileBgLabel input { display: none; }
.profileStripeLabel:has(input:checked), .profileBgLabel:has(input:checked) {
background: rgb(0 0 0 / 12%);
}
div#stripeContainer, div#bgContainer {
align-items: baseline;
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
height: 193px;
overflow-x: auto;
overflow-y: hidden;
}
label.fillingCategoryRadio {
border-radius: 16px;
border: 1px solid var(--borders);
background: var(--beg300);
padding: 2px 6px;
display: inline-block;
margin: 0px 4px 5px 0px;
}
label.fillingCategoryRadio:has(input:checked) {
background: var(--borders);
color: var(--text1);
}
.fillingCategoryRadio input[type="radio"] {
display: none;
}
label.fillingCategoryRadio {
cursor: pointer;
}
.profileDescr, .profileStripe, .profileBg { display: none; }
.fillingCategoryRadio:has(#profileDescr:checked) ~ .profileDescr {
display: block !important;
}
.fillingCategoryRadio:has(#profileStripe:checked) ~ .profileStripe {
display: block !important;
}
.fillingCategoryRadio:has(#profileBg:checked) ~ .profileBg {
display: block !important;
}
.fillingForm { text-align: center; }
.instructionBlock hr {
border: solid 1px var(--borders);
margin: 10px;
}
</style>
[/html]





















