Mudanças entre as edições de "Widget:C.Background"

De Wiki Gla
Ir para navegação Ir para pesquisar
(Criou página com '<!-- BACKGROUND SYSTEM --> <script> (function () { 'use strict'; const { filePathURL } = window.__CBase || {}; function buildBgURL(fileName) {...')
 
m
 
Linha 1: Linha 1:
<!-- BACKGROUND SYSTEM -->
<!-- ===========================
    BACKGROUND SYSTEM (com cache persistente)
    =========================== -->
<script>
<script>
    /**
    * @typedef {Object} MediaWiki
    * @property {Object} util
    * @property {Function} util.wikiScript
    * @property {Function} util.wikiUrlencode
    * @property {Object} config
    * @property {Function} config.get
    */
    // @ts-ignore - MediaWiki global
    var mw = window.mw || {};
     (function () {
     (function () {
         'use strict';
         /**
        const { filePathURL } = window.__CBase || {};
        * Builds a MediaWiki file URL from a filename
 
        * @param {string} fileName - The filename (with or without "Arquivo:" prefix)
        * @returns {string} The full URL to the file
        */
         function buildBgURL(fileName) {
         function buildBgURL(fileName) {
            if (filePathURL) return filePathURL(fileName);
             if (!fileName) return '';
             if (!fileName) return '';
             const base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function')
             var base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function')
                 ? mw.util.wikiScript()
                 ? mw.util.wikiScript()
                 : (window.mw && window.mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
                 : (window.mw && mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
             const path = 'Especial:FilePath/' + fileName.replace(/^Arquivo:|^File:/, '');
             var path = 'Especial:FilePath/' + fileName.replace(/^Arquivo:|^File:/, '');
             if (window.mw && mw.util && typeof mw.util.wikiUrlencode === 'function') {
             if (window.mw && mw.util && typeof mw.util.wikiUrlencode === 'function') {
                 return base + '?title=' + mw.util.wikiUrlencode(path);
                 return base + '?title=' + mw.util.wikiUrlencode(path);
Linha 19: Linha 33:
         }
         }


        /**
        * Sistema de cache persistente usando IndexedDB
        */
        var BgCache = (function () {
            var DB_NAME = 'character-bg-cache';
            var DB_VERSION = 1;
            var STORE_NAME = 'backgrounds';
            var db = null;
            /**
            * Inicializa o banco de dados IndexedDB
            */
            function initDB() {
                return new Promise(function (resolve, reject) {
                    if (db) {
                        resolve(db);
                        return;
                    }
                    if (!window.indexedDB) {
                        reject(new Error('IndexedDB não disponível'));
                        return;
                    }
                    var request = indexedDB.open(DB_NAME, DB_VERSION);
                    request.onerror = function () {
                        reject(request.error);
                    };
                    request.onsuccess = function () {
                        db = request.result;
                        resolve(db);
                    };
                    request.onupgradeneeded = function (event) {
                        var database = event.target.result;
                        if (!database.objectStoreNames.contains(STORE_NAME)) {
                            database.createObjectStore(STORE_NAME);
                        }
                    };
                });
            }
            /**
            * Obtém imagem do cache
            * @param {string} url - URL da imagem
            * @returns {Promise<string|null>} URL do blob ou null se não estiver em cache
            */
            function get(url) {
                return initDB().then(function (database) {
                    return new Promise(function (resolve, reject) {
                        var transaction = database.transaction([STORE_NAME], 'readonly');
                        var store = transaction.objectStore(STORE_NAME);
                        var request = store.get(url);
                        request.onsuccess = function () {
                            var blob = request.result;
                            if (blob && blob instanceof Blob) {
                                var blobUrl = URL.createObjectURL(blob);
                                resolve(blobUrl);
                            } else {
                                resolve(null);
                            }
                        };
                        request.onerror = function () {
                            reject(request.error);
                        };
                    });
                }).catch(function () {
                    return Promise.resolve(null);
                });
            }
            /**
            * Salva imagem no cache
            * @param {string} url - URL da imagem
            * @param {Blob} blob - Blob da imagem
            */
            function set(url, blob) {
                initDB().then(function (database) {
                    var transaction = database.transaction([STORE_NAME], 'readwrite');
                    var store = transaction.objectStore(STORE_NAME);
                    store.put(blob, url);
                }).catch(function () {
                    // Falha silenciosa - cache opcional
                });
            }
            /**
            * Carrega imagem e aplica cache
            * @param {string} url - URL da imagem
            * @returns {Promise<string>} URL do blob (do cache ou recém-carregada)
            */
            function loadImage(url) {
                return get(url).then(function (cachedUrl) {
                    if (cachedUrl) {
                        return Promise.resolve(cachedUrl);
                    }
                    // Carrega a imagem e salva no cache
                    return fetch(url, { mode: 'cors' }).then(function (response) {
                        if (!response.ok) {
                            throw new Error('Falha ao carregar imagem: ' + response.status);
                        }
                        return response.blob();
                    }).then(function (blob) {
                        set(url, blob);
                        return URL.createObjectURL(blob);
                    });
                }).catch(function () {
                    // Em caso de erro, retorna a URL original
                    return Promise.resolve(url);
                });
            }
            return {
                loadImage: loadImage
            };
        })();
        /**
        * Applies background image to an element (com cache persistente)
        * @param {HTMLElement} el - The element to apply background to
        */
         function applyBg(el) {
         function applyBg(el) {
             try {
             try {
                 let url = el.getAttribute('data-bg-url');
                 var url = el.getAttribute('data-bg-url');
                 if (!url) {
                 if (!url) {
                     const f = el.getAttribute('data-bg-file');
                     var f = el.getAttribute('data-bg-file');
                     if (f) {
                     if (f) {
                         url = buildBgURL(f);
                         url = buildBgURL(f);
Linha 29: Linha 169:
                     }
                     }
                 }
                 }
                 if (url) {
                 if (url) {
                     el.style.backgroundImage = 'url("' + url + '")';
                     // Tenta carregar do cache primeiro
                    BgCache.loadImage(url).then(function (blobUrl) {
                        el.style.backgroundImage = 'url("' + blobUrl + '")';
                        // Remove o atributo temporário se existir
                        el.removeAttribute('data-bg-loading');
                    }).catch(function () {
                        // Fallback para URL original em caso de erro
                        el.style.backgroundImage = 'url("' + url + '")';
                    });
 
                    // Aplica URL original imediatamente enquanto carrega do cache (progressive enhancement)
                    if (!el.hasAttribute('data-bg-loading')) {
                        el.setAttribute('data-bg-loading', '1');
                        el.style.backgroundImage = 'url("' + url + '")';
                    }
                 }
                 }
             } catch (e) {
             } catch (e) {
                 // no-op
                 /* no-op */
             }
             }
         }
         }
Linha 41: Linha 196:


         // Apply to future elements (AJAX)
         // Apply to future elements (AJAX)
         if (window.MutationObserver) {
         new MutationObserver(function (mutations) {
            new MutationObserver(function (mutations) {
            mutations.forEach(function (m) {
                mutations.forEach(function (m) {
                if (m.type === 'childList') {
                    if (m.type === 'childList') {
                    m.addedNodes.forEach(function (n) {
                        m.addedNodes.forEach(function (n) {
                        if (n.nodeType === 1) {
                            if (n.nodeType === 1) {
                            if (n.hasAttribute && (n.hasAttribute('data-bg-file') || n.hasAttribute('data-bg-url'))) {
                                if (n.hasAttribute && (n.hasAttribute('data-bg-file') || n.hasAttribute('data-bg-url'))) {
                                applyBg(n);
                                    applyBg(n);
                                }
                                if (n.querySelectorAll) {
                                    n.querySelectorAll('[data-bg-file], [data-bg-url]').forEach(applyBg);
                                }
                             }
                             }
                         });
                            if (n.querySelectorAll) {
                    } else if (m.type === 'attributes' && m.target) {
                                n.querySelectorAll('[data-bg-file], [data-bg-url]').forEach(applyBg);
                        applyBg(m.target);
                            }
                    }
                         }
                 });
                    });
            }).observe(document.body, {
                } else if (m.type === 'attributes' && m.target) {
                attributes: true,
                    applyBg(m.target);
                attributeFilter: ['data-bg-file', 'data-bg-url'],
                 }
                childList: true,
                subtree: true,
             });
             });
         }
         }).observe(document.body, {
            attributes: true,
            attributeFilter: ['data-bg-file', 'data-bg-url'],
            childList: true,
            subtree: true,
        });
     })();
     })();
</script>
</script>

Edição atual tal como às 15h09min de 2 de janeiro de 2026

<script>

   /**
    * @typedef {Object} MediaWiki
    * @property {Object} util
    * @property {Function} util.wikiScript
    * @property {Function} util.wikiUrlencode
    * @property {Object} config
    * @property {Function} config.get
    */
   // @ts-ignore - MediaWiki global
   var mw = window.mw || {};
   (function () {
       /**
        * Builds a MediaWiki file URL from a filename
        * @param {string} fileName - The filename (with or without "Arquivo:" prefix)
        * @returns {string} The full URL to the file
        */
       function buildBgURL(fileName) {
           if (!fileName) return ;
           var base = (window.mw && mw.util && typeof mw.util.wikiScript === 'function')
               ? mw.util.wikiScript()
               : (window.mw && mw.config ? (mw.config.get('wgScript') || '/index.php') : '/index.php');
           var path = 'Especial:FilePath/' + fileName.replace(/^Arquivo:|^File:/, );
           if (window.mw && mw.util && typeof mw.util.wikiUrlencode === 'function') {
               return base + '?title=' + mw.util.wikiUrlencode(path);
           } else {
               return base + '?title=' + encodeURIComponent(path).replace(/%2F/g, '/');
           }
       }
       /**
        * Sistema de cache persistente usando IndexedDB
        */
       var BgCache = (function () {
           var DB_NAME = 'character-bg-cache';
           var DB_VERSION = 1;
           var STORE_NAME = 'backgrounds';
           var db = null;
           /**
            * Inicializa o banco de dados IndexedDB
            */
           function initDB() {
               return new Promise(function (resolve, reject) {
                   if (db) {
                       resolve(db);
                       return;
                   }
                   if (!window.indexedDB) {
                       reject(new Error('IndexedDB não disponível'));
                       return;
                   }
                   var request = indexedDB.open(DB_NAME, DB_VERSION);
                   request.onerror = function () {
                       reject(request.error);
                   };
                   request.onsuccess = function () {
                       db = request.result;
                       resolve(db);
                   };
                   request.onupgradeneeded = function (event) {
                       var database = event.target.result;
                       if (!database.objectStoreNames.contains(STORE_NAME)) {
                           database.createObjectStore(STORE_NAME);
                       }
                   };
               });
           }
           /**
            * Obtém imagem do cache
            * @param {string} url - URL da imagem
            * @returns {Promise<string|null>} URL do blob ou null se não estiver em cache
            */
           function get(url) {
               return initDB().then(function (database) {
                   return new Promise(function (resolve, reject) {
                       var transaction = database.transaction([STORE_NAME], 'readonly');
                       var store = transaction.objectStore(STORE_NAME);
                       var request = store.get(url);
                       request.onsuccess = function () {
                           var blob = request.result;
                           if (blob && blob instanceof Blob) {
                               var blobUrl = URL.createObjectURL(blob);
                               resolve(blobUrl);
                           } else {
                               resolve(null);
                           }
                       };
                       request.onerror = function () {
                           reject(request.error);
                       };
                   });
               }).catch(function () {
                   return Promise.resolve(null);
               });
           }
           /**
            * Salva imagem no cache
            * @param {string} url - URL da imagem
            * @param {Blob} blob - Blob da imagem
            */
           function set(url, blob) {
               initDB().then(function (database) {
                   var transaction = database.transaction([STORE_NAME], 'readwrite');
                   var store = transaction.objectStore(STORE_NAME);
                   store.put(blob, url);
               }).catch(function () {
                   // Falha silenciosa - cache opcional
               });
           }
           /**
            * Carrega imagem e aplica cache
            * @param {string} url - URL da imagem
            * @returns {Promise<string>} URL do blob (do cache ou recém-carregada)
            */
           function loadImage(url) {
               return get(url).then(function (cachedUrl) {
                   if (cachedUrl) {
                       return Promise.resolve(cachedUrl);
                   }
                   // Carrega a imagem e salva no cache
                   return fetch(url, { mode: 'cors' }).then(function (response) {
                       if (!response.ok) {
                           throw new Error('Falha ao carregar imagem: ' + response.status);
                       }
                       return response.blob();
                   }).then(function (blob) {
                       set(url, blob);
                       return URL.createObjectURL(blob);
                   });
               }).catch(function () {
                   // Em caso de erro, retorna a URL original
                   return Promise.resolve(url);
               });
           }
           return {
               loadImage: loadImage
           };
       })();
       /**
        * Applies background image to an element (com cache persistente)
        * @param {HTMLElement} el - The element to apply background to
        */
       function applyBg(el) {
           try {
               var url = el.getAttribute('data-bg-url');
               if (!url) {
                   var f = el.getAttribute('data-bg-file');
                   if (f) {
                       url = buildBgURL(f);
                       el.setAttribute('data-bg-url', url);
                   }
               }
               if (url) {
                   // Tenta carregar do cache primeiro
                   BgCache.loadImage(url).then(function (blobUrl) {
                       el.style.backgroundImage = 'url("' + blobUrl + '")';
                       // Remove o atributo temporário se existir
                       el.removeAttribute('data-bg-loading');
                   }).catch(function () {
                       // Fallback para URL original em caso de erro
                       el.style.backgroundImage = 'url("' + url + '")';
                   });
                   // Aplica URL original imediatamente enquanto carrega do cache (progressive enhancement)
                   if (!el.hasAttribute('data-bg-loading')) {
                       el.setAttribute('data-bg-loading', '1');
                       el.style.backgroundImage = 'url("' + url + '")';
                   }
               }
           } catch (e) {
               /* no-op */
           }
       }
       // Aplicar backgrounds imediatamente
       document.querySelectorAll('[data-bg-url], [data-bg-file]').forEach(applyBg);
       // Apply to future elements (AJAX)
       new MutationObserver(function (mutations) {
           mutations.forEach(function (m) {
               if (m.type === 'childList') {
                   m.addedNodes.forEach(function (n) {
                       if (n.nodeType === 1) {
                           if (n.hasAttribute && (n.hasAttribute('data-bg-file') || n.hasAttribute('data-bg-url'))) {
                               applyBg(n);
                           }
                           if (n.querySelectorAll) {
                               n.querySelectorAll('[data-bg-file], [data-bg-url]').forEach(applyBg);
                           }
                       }
                   });
               } else if (m.type === 'attributes' && m.target) {
                   applyBg(m.target);
               }
           });
       }).observe(document.body, {
           attributes: true,
           attributeFilter: ['data-bg-file', 'data-bg-url'],
           childList: true,
           subtree: true,
       });
   })();

</script>