İçeriğe geç

JavaScript API

Yükleyici window.MiracOzdemirWidget adında dondurulmuş (frozen) bir nesne tanımlar. Aşağıdaki tipler yükleyici 1.1.0 içindir:

interface MiracOzdemirWidgetApi {
readonly version: '1';
readonly build: string; // örn. '1.1.0'
readonly features: readonly string[]; // yükleyicinin yetenekleri
mount(el: Element): HTMLIFrameElement | null;
unmount(el: Element): boolean;
unmountAll(): number;
scan(root?: ParentNode): number;
update(el: Element, patch: WidgetPatch): boolean;
setInputs(el: Element, values: Record<string, string | number | boolean>, options?: { autorun?: boolean }): boolean;
calculate(el: Element, options?: { timeoutMs?: number }): Promise<{ data: unknown; meta: unknown; inputs: unknown }>;
reset(el: Element): boolean;
get(el: Element): WidgetInstance | null;
getResult(el: Element): { data: unknown; meta: unknown; inputs: unknown } | null;
}
Üye Ne yapar
version Protokol/yükleyici ana sürümü ("1").
build Yükleyici yapı sürümü, semver ("1.1.0").
features Yükleyici yetenekleri: update, inputs, calculate, reset, inherit-theme, kinds, custom-elements.
mount(el) el üzerindeki data-* seçeneklerini okur, doğrular ve iframe kurar. İframe’i döner; seçenekler geçersizse console.warn yazar ve null döner. Öğe zaten mount edilmişse mevcut iframe’i döner (çift widget oluşmaz).
unmount(el) iframe’i kaldırır ve öğeyi temizler. Kaldırıldıysa true döner. Bekleyen calculate() çağrıları UNMOUNTED koduyla reddedilir.
unmountAll() Sayfadaki tüm widget’ları kaldırır; kaldırılan sayıyı döner.
scan(root?) root (varsayılan document) içindeki [data-mo-tool], [data-mo-search], [data-mo-category] öğelerinden henüz mount edilmemişleri mount eder; yeni mount edilen sayısını döner. Ayrıca DOM’dan ayrılmış eski örnekleri temizler.
update(el, patch) Seçenekleri değiştirir; mümkünse yeniden yüklemeden (aşağıya bakın). Bir şey değiştiyse true döner.
setInputs(el, values, { autorun }) Hesaplayıcı widget’ının girdilerini doldurur. el mount edilmiş bir hesaplayıcı değilse false döner.
calculate(el, { timeoutMs }) Formu doğrular ve hesaplar; Promise döner.
reset(el) Formu ve son sonucu sıfırlar.
get(el) Örneğin anlık görüntüsünü ya da null döner.
getResult(el) Son sonucu ({ data, meta, inputs }) ya da null döner.

Yükleyici DOMContentLoaded’da (veya betik geç yüklenmişse hemen) bir kez scan() çağırır. Betiği ikinci kez eklemek yalnızca yeniden scan() yapar; tek bir message dinleyicisi vardır.

Kapsayıcıyı sonradan ekleme:

const container = document.createElement('div');
container.dataset.moTool = 'kdv';
container.dataset.locale = 'tr';
document.querySelector('#hesaplayici').append(container);
window.MiracOzdemirWidget.mount(container);

Bir bölümü yeniden tarama (ör. AJAX ile gelen HTML sonrası):

const added = window.MiracOzdemirWidget.scan(document.querySelector('#yeni-icerik'));
console.log(`${added} widget eklendi`);

Widget’ı kaldırma:

window.MiracOzdemirWidget.unmount(container);

Seçenekleri çalışma anında değiştirir. Bir yama (patch) nesnesi alır; geçersiz veya bilinmeyen alanlar yok sayılır.

const widget = window.MiracOzdemirWidget;
widget.update(container, { theme: 'dark', accent: '0a7d5a', radius: 'lg' }); // anında, yeniden yükleme yok
widget.update(container, { accent: null }); // site rengine dön
widget.update(container, { locale: 'en' }); // iframe yeniden yüklenir
Alan Değerler Davranış
theme auto, light, dark, inherit canlı
header true/false canlı
density comfortable, compact canlı
radius none, sm, md, lg canlı
accent 6 onaltılık hane (# isteğe bağlı) veya null canlı
view full, result (hesaplayıcı) canlı
height px, 120–10000 iframe yüksekliği hemen ayarlanır
title metin (≤ 200) iframe title’ı
locale tr, en yeniden yükleme
tool araç anahtarı (hesaplayıcı) yeniden yükleme
category kategori anahtarı (kategori widget’ında anahtar, arama widget’ında filtre) yeniden yükleme
target _blank, event (arama/kategori) yeniden yükleme

“Canlı” değişiklikler iframe’e bir config mesajıyla iletilir; iframe hazır değilse sıraya alınır, embed sayfası config özelliğini desteklemiyorsa (eski sürüm) yükleyici iframe’i yeniden yükler. Yeniden yükleme, iframe’in src’sini güncel seçeneklerle yeniden kurmaktır; kapsayıcı öğe değişmez. update ayrıca kapsayıcının data-* özniteliklerini yeni değerlerle günceller.

widget.setInputs(container, { amount: '2500', mode: 'exclusive' }, { autorun: true }); // true

Değerler data-input-* ile aynı kurallara tabidir: alan adı ^[a-z][A-Za-z0-9_]{0,63}$, en çok 50 alan, değer ≤ 64 karakter, ondalıklar string; geçersizler atlanır. autorun: true girdiler uygulandıktan hemen sonra hesaplar. iframe henüz hazır değilse çağrı sıraya alınır. Eski bir embed sayfasında yükleyici girdileri adrese koyup iframe’i yeniden yükler.

try {
const { data, meta, inputs } = await widget.calculate(container, { timeoutMs: 10_000 });
console.log(data.result, meta.asOf, inputs);
} catch (error) {
// error bir Error değil, { code, message, fields? } nesnesidir
console.warn(error.code, error.fields);
}
  • timeoutMs: 1000–60000 arası sıkıştırılır, varsayılan 15000; hem hazır olmayı beklemeyi hem hesaplamayı kapsar.
  • Çözülen değer, yanıtla aynı biçimdedir: data (result, breakdown), meta ve istek inputs’u.
  • Form geçersizse VALIDATION_ERROR gibi bir API koduyla ve alan hatalarıyla (fields: [{ field, reason }]) reddedilir; widget aynı hataları kullanıcıya da gösterir.
  • Yükleyici tarafı kodlar: NOT_MOUNTED (öğe mount edilmemiş), NOT_READY (zamanında hazır olmadı), UNSUPPORTED (arama/kategori widget’ı ya da komutu bilmeyen eski embed sayfası), TIMEOUT, UNMOUNTED (beklerken widget kaldırıldı). Embed sayfasından NETWORK_ERROR, INVALID_RESPONSE gibi kodlar da gelebilir: Hata kodları.
widget.reset(container); // true; formu ve son sonucu temizler
const snapshot = widget.get(container);
// { id, kind, ready, height, title, tool: { key, version, title } | null, features,
// options: { kind, key, locale, theme, header, height, accent, radius, density, view, autorun, target, category, inputs },
// result: { data, meta, inputs } | null, inputs: {…} | null }
widget.getResult(container); // son sonuç ya da null

snapshot.inputs, kullanıcının son düzenlemesinden gelen kanonik girdidir (form geçerliyse), aksi halde null.

Betik async yüklendiği için global, kodunuz çalıştığında henüz tanımlı olmayabilir. Güvenli yardımcı:

function whenWidgetReady(callback) {
if (window.MiracOzdemirWidget) return callback(window.MiracOzdemirWidget);
const existing = document.querySelector('script[src$="/widget.js"]');
const script = existing ?? Object.assign(document.createElement('script'), { src: 'https://api.mirac-ozdemir.com/widget.js', async: true });
script.addEventListener('load', () => callback(window.MiracOzdemirWidget), { once: true });
if (!existing) document.head.append(script);
}
whenWidgetReady((widget) => widget.scan());

Tip desteği ve hazır yükleyici yardımcıları için SDK var.

widget.features yükleyicinin, ready olayındaki features ise embed sayfasının yeteneklerini listeler. Eski bir yükleyiciyle (1.0) çalışabilecek kod yazıyorsanız üyeleri kullanmadan önce kontrol edin:

if (window.MiracOzdemirWidget?.features?.includes('update')) {
window.MiracOzdemirWidget.update(container, { theme: 'dark' });
} else {
window.MiracOzdemirWidget?.unmount(container);
container.dataset.theme = 'dark';
window.MiracOzdemirWidget?.mount(container);
}
global.d.ts
interface Window {
MiracOzdemirWidget?: {
readonly version: '1';
readonly build: string;
readonly features: readonly string[];
mount(el: Element): HTMLIFrameElement | null;
unmount(el: Element): boolean;
unmountAll(): number;
scan(root?: ParentNode): number;
update(el: Element, patch: Record<string, unknown>): boolean;
setInputs(el: Element, values: Record<string, string | number | boolean>, options?: { autorun?: boolean }): boolean;
calculate(el: Element, options?: { timeoutMs?: number }): Promise<{ data: unknown; meta: unknown; inputs: unknown }>;
reset(el: Element): boolean;
get(el: Element): unknown | null;
getResult(el: Element): unknown | null;
};
}

Ayrıntılı tipler (WidgetPatch, olay detail tipleri, manifest) SDK paketindedir: Özel öğeler ve SDK.