انتقل إلى المحتوى

ميدياويكي:Common.js

من دَعوة ويكي
مراجعة ١٣:٣٥، ١٨ يونيو ٢٠٢٦ بواسطة DawahAgent (نقاش | مساهمات) (wiki UI footer/panel/Main Page hotfix r2 (owner approved 2026-06-18))

ملاحظة: بعد الحفظ، قد يلزمك محو الاختزان الخاص بمتصفحك لرؤية التغييرات.

  • فايرفوكس / سافاري: أمسك Shift أثناء ضغط Reload، أو اضغط على إما Ctrl-F5 أو Ctrl-R (⌘-R على ماك)
  • جوجل كروم: اضغط Ctrl-Shift-R (⌘-Shift-R على ماك)
  • إنترنت إكسبلورر/إيدج: أمسك Ctrl أثناء ضغط Refresh، أو اضغط Ctrl-F5
  • أوبرا: اضغط Ctrl-F5.
/* URETHANE DESIGN — generic theme engine (app-agnostic).
   Pair with 02-tokens.css. Include synchronously in <head>.
   Sets on <html>: data-du-mode (light|dark, auto-resolved),
   data-du-glass (faithful|modern|flat), inline --du-h (accent hue) and --du-c (accent chroma).
   Prefs: localStorage 'dawahUrethane' + mirrored to a .dawah.wiki cookie
   so the choice follows users across subdomains. Defaults (owner-mandated):
   mode 'auto', glass 'faithful' (the 2006 look), accent '#2e8fc7' (blue).
   Optional: set window.DU_MOUNT = 'css selector' before this script to pick
   where the "Theme" switcher button mounts (default: fixed bottom corner).
*/
(function () {
	'use strict';
	var KEY = 'dawahUrethane';
	var DEFAULTS = { mode: 'auto', glass: 'faithful', accent: '#2e8fc7', t: 0 };
	var PRESETS = [
		['#2e8fc7', 'Urethane blue'], ['#29a395', 'Madinah teal'],
		['#2ea05b', 'Palm green'], ['#d4912a', 'Desert amber'],
		['#7a5cc7', 'Violet'], ['#cc3d77', 'Rose']
	];

	function valid(p) {
		p = p || {};
		return {
			mode: ['auto', 'light', 'dark'].indexOf(p.mode) >= 0 ? p.mode : DEFAULTS.mode,
			glass: ['faithful', 'modern', 'flat'].indexOf(p.glass) >= 0 ? p.glass : DEFAULTS.glass,
			accent: /^#[0-9a-fA-F]{6}$/.test(p.accent || '') ? p.accent : DEFAULTS.accent,
			t: typeof p.t === 'number' ? p.t : 0
		};
	}
	function readLocal() { try { return JSON.parse(localStorage.getItem(KEY) || 'null'); } catch (e) { return null; } }
	function readCookie() {
		var m = document.cookie.match(new RegExp('(?:^|; )' + KEY + '=([^;]*)'));
		if (!m) { return null; }
		try { return JSON.parse(decodeURIComponent(m[1])); } catch (e) { return null; }
	}
	function load() {
		var a = readLocal(), b = readCookie();
		var p = (b && (!a || (b.t || 0) > (a.t || 0))) ? b : a; /* newer wins */
		return valid(p);
	}
	function save(p) {
		p.t = Date.now();
		var s = JSON.stringify(p);
		try { localStorage.setItem(KEY, s); } catch (e) { /* private mode */ }
		try {
			document.cookie = KEY + '=' + encodeURIComponent(s) +
				'; domain=.dawah.wiki; path=/; max-age=31536000; SameSite=Lax; Secure';
		} catch (e) { /* file:// etc. */ }
	}

	function hexToHue(hex) {
		var r = parseInt(hex.substr(1, 2), 16) / 255,
			g = parseInt(hex.substr(3, 2), 16) / 255,
			b = parseInt(hex.substr(5, 2), 16) / 255;
		var max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min, h = 0;
		if (d === 0) { return 205; } /* achromatic: keep blue chrome */
		if (max === r) { h = ((g - b) / d) % 6; }
		else if (max === g) { h = (b - r) / d + 2; }
		else { h = (r - g) / d + 4; }
		return (Math.round(h * 60) + 360) % 360;
	}

	function hexToChroma(hex) {
		var r = parseInt(hex.substr(1, 2), 16) / 255,
			g = parseInt(hex.substr(3, 2), 16) / 255,
			b = parseInt(hex.substr(5, 2), 16) / 255;
		var d = Math.max(r, g, b) - Math.min(r, g, b);
		var base = 153 / 255; /* #2e8fc7, the default Urethane blue */
		return Math.max(0, Math.min(1.25, d / base));
	}

	var mq = window.matchMedia ? window.matchMedia('(prefers-color-scheme: dark)') : null;

	function apply() {
		var p = load();
		var mode = p.mode === 'auto' ? (mq && mq.matches ? 'dark' : 'light') : p.mode;
		var de = document.documentElement;
		de.setAttribute('data-du-mode', mode);
		de.setAttribute('data-du-glass', p.glass);
		de.style.setProperty('--du-h', String(hexToHue(p.accent)));
		de.style.setProperty('--du-c', String(hexToChroma(p.accent)));
	}

	apply();
	if (mq) {
		var onChange = function () { if (load().mode === 'auto') { apply(); } };
		if (mq.addEventListener) { mq.addEventListener('change', onChange); }
		else if (mq.addListener) { mq.addListener(onChange); }
	}

	/* ---------------- switcher UI ---------------- */
	function el(tag, cls, text) {
		var e = document.createElement(tag);
		if (cls) { e.className = cls; }
		if (text) { e.textContent = text; }
		return e;
	}

	function buildPanel(anchor) {
		var p = load();
		var panel = el('div'); panel.id = 'du-panel';
		panel.setAttribute('role', 'dialog');
		panel.setAttribute('aria-label', 'Theme options');
		panel.style.cssText = 'position:absolute;z-index:9999;inset-inline-end:0;bottom:calc(100% + 8px);width:248px;background:var(--du-panel);border:1px solid var(--du-edge);border-radius:10px;box-shadow:var(--du-psh),0 6px 22px rgb(0 0 0 / .25);padding:12px;color:var(--du-text);font-size:12px;text-align:start';

		function section(title) {
			var h = el('h4', null, title);
			h.style.cssText = 'margin:0 0 4px;font-size:11px;text-transform:uppercase;letter-spacing:.4px;color:var(--du-muted)';
			panel.appendChild(h);
			var row = el('div'); row.style.cssText = 'display:flex;gap:5px;flex-wrap:wrap;margin-bottom:10px';
			panel.appendChild(row); return row;
		}
		function styleOpt(o, on) {
			o.style.cssText = 'flex:1;text-align:center;padding:5px 8px;border:1px solid var(--du-edge);border-radius:7px;cursor:pointer;white-space:nowrap;' +
				(on ? 'background:var(--du-prim);color:#fff;text-shadow:0 1px rgb(0 0 0 / .3)'
					: 'background:var(--du-face);box-shadow:var(--du-bev);color:var(--du-text);text-shadow:var(--du-tsh)');
		}
		function opts(row, items, key, current) {
			items.forEach(function (it) {
				var o = el('span', null, it[1]);
				o.setAttribute('role', 'button'); o.tabIndex = 0;
				styleOpt(o, current === it[0]);
				var act = function () {
					var np = load(); np[key] = it[0]; save(np); apply();
					Array.prototype.forEach.call(row.children, function (c, i) { styleOpt(c, items[i][0] === it[0]); });
				};
				o.addEventListener('click', act);
				o.addEventListener('keydown', function (ev) { if (ev.key === 'Enter' || ev.key === ' ') { ev.preventDefault(); act(); } });
				row.appendChild(o);
			});
		}

		opts(section('Mode'), [['auto', 'Auto'], ['light', 'Light'], ['dark', 'Dark']], 'mode', p.mode);
		opts(section('Glass'), [['faithful', '2006'], ['modern', 'Modern'], ['flat', 'Flat']], 'glass', p.glass);

		var crow = section('Accent');
		function ring(s, on) { s.style.outline = on ? '2px solid var(--du-link)' : 'none'; s.style.outlineOffset = '2px'; }
		var swatches = [];
		PRESETS.forEach(function (pr) {
			var s = el('button'); s.type = 'button'; s.title = pr[1];
			s.setAttribute('aria-label', pr[1]);
			s.style.cssText = 'width:24px;height:24px;border-radius:50%;border:1px solid var(--du-edge);cursor:pointer;padding:0;box-shadow:inset 0 1px rgb(255 255 255 / .55);background:' + pr[0];
			ring(s, p.accent.toLowerCase() === pr[0]);
			s.addEventListener('click', function () {
				var np = load(); np.accent = pr[0]; save(np); apply();
				swatches.forEach(function (x) { ring(x, x === s); });
				picker.value = pr[0];
			});
			swatches.push(s); crow.appendChild(s);
		});
		var picker = document.createElement('input');
		picker.type = 'color'; picker.value = p.accent; picker.title = 'Custom color';
		picker.setAttribute('aria-label', 'Custom accent color');
		picker.style.cssText = 'width:34px;height:26px;padding:0;border:1px solid var(--du-edge);border-radius:6px;background:var(--du-panel);cursor:pointer';
		picker.addEventListener('input', function () {
			var np = load(); np.accent = picker.value; save(np); apply();
			swatches.forEach(function (x) { ring(x, false); });
		});
		crow.appendChild(picker);

		var note = el('p', null, 'Applies across dawah.wiki in this browser.');
		note.style.cssText = 'color:var(--du-muted);font-size:11px;margin:2px 0 0';
		panel.appendChild(note);
		anchor.appendChild(panel);
		return panel;
	}

	function buildFab() {
		var mount = window.DU_MOUNT ? document.querySelector(window.DU_MOUNT) : null;
		var li = el(mount ? 'span' : 'div');
		li.style.position = 'relative';
		if (mount) { mount.appendChild(li); }
		else {
			li.style.cssText += ';position:fixed;bottom:14px;inset-inline-end:14px;z-index:9998';
			document.body.appendChild(li);
		}
		var fab = el('a', null, 'Theme'); fab.id = 'du-fab'; fab.href = '#';
		fab.setAttribute('role', 'button');
		fab.setAttribute('aria-haspopup', 'dialog');
		fab.title = 'Theme options';
		fab.style.cssText = 'display:inline-flex;align-items:center;gap:6px;cursor:pointer;user-select:none;padding:6px 12px;border:1px solid var(--du-edge);border-radius:7px;background:var(--du-face);box-shadow:var(--du-bev);color:var(--du-text);text-shadow:var(--du-tsh);text-decoration:none;font-size:12.5px';
		var dot = el('span'); dot.setAttribute('aria-hidden', 'true');
		dot.style.cssText = 'width:12px;height:12px;border-radius:50%;background:hsl(var(--du-h) calc(70% * var(--du-c)) 50%);box-shadow:inset 0 1px rgb(255 255 255 / .6)';
		fab.insertBefore(dot, fab.firstChild);
		li.appendChild(fab);

		var panel = null;
		fab.addEventListener('click', function (ev) {
			ev.preventDefault();
			if (panel) { panel.parentNode.removeChild(panel); panel = null; return; }
			panel = buildPanel(li);
		});
		document.addEventListener('click', function (ev) {
			if (panel && !li.contains(ev.target)) { panel.parentNode.removeChild(panel); panel = null; }
		});
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', buildFab);
	} else {
		buildFab();
	}
})();

/* MediaWiki footer polish: replace stock wiki footer links with site-wide public links. */
(function () {
  'use strict';
  function ready(fn) {
    if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', fn); }
    else { fn(); }
  }
  function footerLinks() {
    var places = document.getElementById('footer-places');
    if (!places) { return; }
    var info = document.getElementById('footer-info');
    var isAr = (document.documentElement.lang || '').toLowerCase().indexOf('ar') === 0 || document.documentElement.dir === 'rtl';
    var links = isAr ? [
      ['عن', 'https://dawah.wiki/about'],
      ['الإرشادات', 'https://dawah.wiki/guidelines'],
      ['الخصوصية', 'https://dawah.wiki/privacy'],
      ['اتصل بنا', 'https://dawah.wiki/contact']
    ] : [
      ['About', 'https://dawah.wiki/about'],
      ['Guidelines', 'https://dawah.wiki/guidelines'],
      ['Privacy', 'https://dawah.wiki/privacy'],
      ['Contact', 'https://dawah.wiki/contact']
    ];
    if (places.getAttribute('data-dw-polished') !== '1') {
      places.textContent = '';
      links.forEach(function (item) {
        var li = document.createElement('li');
        var a = document.createElement('a');
        a.href = item[1];
        a.textContent = item[0];
        li.appendChild(a);
        places.appendChild(li);
      });
      places.setAttribute('data-dw-polished', '1');
    }
    if (info) {
      info.textContent = '';
      var copy = document.createElement('li');
      copy.id = 'footer-info-copyright';
      copy.textContent = isAr ? '© 2026 Dawah.Wiki. جميع الحقوق محفوظة.' : '© 2026 Dawah.Wiki. All rights reserved.';
      info.appendChild(copy);
    }
  }
  ready(footerLinks);
}());


/* IMPLEMENTAUDIT wiki-ui-polish 2026-06-18: canonical wiki platform nav. */
(function () {
  'use strict';
  window.DU_MOUNT = '#du-theme-slot';
  function ready(fn) {
    if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', fn); }
    else { fn(); }
  }
  function icon(name) {
    var paths = {
      home: '<path d="M3 10.5 12 3l9 7.5"/><path d="M5 9.5V21h5v-6h4v6h5V9.5"/>',
      wiki: '<path d="M5 5h14v14H5z"/><path d="M8 9h8M8 13h8"/>',
      forum: '<path d="M4 6h16v10H8l-4 4z"/>',
      markdown: '<path d="M3 7h18v10H3z"/><path d="M7 14V10l2 2 2-2v4M15 10v4M13 12l2 2 2-2"/>',
      gallery: '<path d="M4 5h16v14H4z"/><path d="m7 16 3-4 3 3 2-2 2 3"/><circle cx="9" cy="9" r="1.5"/>',
      qamus: '<path d="M7 4h9a3 3 0 0 1 3 3v13H8a3 3 0 0 1-3-3V6a2 2 0 0 1 2-2z"/><path d="M8 4v13a3 3 0 0 0 3 3"/>'
    };
    return '<span class="ic" aria-hidden="true"><svg viewBox="0 0 24 24">' + (paths[name] || '') + '</svg></span>';
  }
  function makeLink(item, currentHost) {
    var a = document.createElement('a');
    a.href = item.href;
    a.innerHTML = icon(item.icon) + '<span>' + item.label + '</span>';
    if (item.current || currentHost === item.host) { a.setAttribute('aria-current', 'page'); }
    return a;
  }
  function loginHref() {
    var login = document.querySelector('#pt-login-2 a, #pt-login a, a[href*="Special:UserLogin"]');
    return login ? login.href : 'https://forum.dawah.wiki/ucp.php?mode=login';
  }
  function moveThemeFab() {
    var slot = document.getElementById('du-theme-slot');
    var fab = document.getElementById('du-fab');
    if (!slot || !fab) { return; }
    var wrap = fab.parentElement;
    if (wrap && wrap.parentElement !== slot) {
      wrap.style.position = 'relative';
      wrap.style.insetInlineEnd = '';
      wrap.style.bottom = '';
      wrap.style.zIndex = '';
      slot.appendChild(wrap);
    }
  }
  function wireThemeDismissal() {
    if (wireThemeDismissal.done) { return; }
    wireThemeDismissal.done = true;
    document.addEventListener('keydown', function (ev) {
      if (ev.key !== 'Escape' || !document.getElementById('du-panel')) { return; }
      ev.preventDefault();
      document.body.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
      var fab = document.getElementById('du-fab');
      if (fab) { fab.focus(); }
    });
  }
  function ensureWikiNav() {
    if (document.querySelector('.duglobal[data-dw-wiki-nav="1"]')) { moveThemeFab(); return; }
    var header = document.querySelector('.vector-header-container');
    if (!header || !document.body.classList.contains('skin-vector')) { return; }
    var host = location.hostname;
    var isAr = host.indexOf('ar.') === 0 || document.documentElement.dir === 'rtl';
    var nav = document.createElement('header');
    nav.className = 'du-chrome duglobal';
    nav.setAttribute('role', 'banner');
    nav.setAttribute('data-dw-wiki-nav', '1');
    var inner = document.createElement('div');
    inner.className = 'duglobal-in';
    var brand = document.createElement('a');
    brand.className = 'brand';
    brand.href = 'https://dawah.wiki/';
    brand.innerHTML = '<img class="crest" src="/resources/assets/dawahwiki-logo-135.png" alt=""><span class="wm">Dawah.Wiki</span>';
    var tabs = document.createElement('nav');
    tabs.className = 'switch';
    tabs.setAttribute('aria-label', 'Platform');
    [
      {label:'Home', href:'https://dawah.wiki/', icon:'home', host:'dawah.wiki'},
      {label:'Wiki', href:isAr ? 'https://ar.dawah.wiki/' : 'https://en.dawah.wiki/', icon:'wiki', current:true},
      {label:'Forum', href:'https://forum.dawah.wiki/', icon:'forum'},
      {label:'Markdown', href:'https://md.dawah.wiki/', icon:'markdown'},
      {label:'Gallery', href:'https://gallery.dawah.wiki/', icon:'gallery'},
      {label:'Qamus', href:'https://qamus.dawah.wiki/', icon:'qamus'}
    ].forEach(function (item) { tabs.appendChild(makeLink(item, host)); });
    var right = document.createElement('div');
    right.className = 'gright';
    var lang = document.createElement('span');
    lang.className = 'langtog';
    lang.setAttribute('aria-label', 'Language');
    lang.innerHTML = '<a href="https://en.dawah.wiki/"' + (!isAr ? ' aria-current="true"' : '') + '>EN</a><a href="https://ar.dawah.wiki/"' + (isAr ? ' aria-current="true"' : '') + ' lang="ar" dir="rtl">ع</a>';
    var theme = document.createElement('span');
    theme.id = 'du-theme-slot';
    var who = document.createElement('span');
    who.className = 'who';
    var auth = document.createElement('a');
    auth.className = 'du-login';
    auth.href = loginHref();
    auth.textContent = isAr ? 'دخول / تسجيل' : 'Login / Register';
    who.appendChild(auth);
    right.appendChild(lang);
    right.appendChild(theme);
    right.appendChild(who);
    inner.appendChild(brand);
    inner.appendChild(tabs);
    inner.appendChild(right);
    nav.appendChild(inner);
    header.parentNode.insertBefore(nav, header);
    moveThemeFab();
    wireThemeDismissal();
    setTimeout(moveThemeFab, 0);
    setTimeout(moveThemeFab, 250);
  }
  ready(ensureWikiNav);
})();
/* /IMPLEMENTAUDIT wiki-ui-polish 2026-06-18 */