Plugin Directory

Changeset 3766720


Ignore:
Timestamp:
10/26/2026 02:48:50 PM (3 days ago)
Author:
pluginpeer
Message:

Release 1.2.23

Location:
ppeer-glitchpin
Files:
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • ppeer-glitchpin/tags/1.2.23/languages/ppeer-glitchpin.pot

    r3766437 r3766720  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: GlitchPin - Visual Bug Feedback 1.2.12\n"
     5"Project-Id-Version: GlitchPin - Visual Bug Feedback 1.2.23\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ppeer-glitchpin\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  • ppeer-glitchpin/tags/1.2.23/ppeer-glitchpin.php

    r3766437 r3766720  
    33 * Plugin Name: GlitchPin - Visual Bug Feedback
    44 * Description: Collect private, local bug reports with screenshots and page context.
    5  * Version: 1.2.12
     5 * Version: 1.2.23
    66 * Requires at least: 6.4
    77 * Requires PHP: 8.3
    … …  
    1818defined( 'ABSPATH' ) || exit;
    1919
    20 define( 'PPBH_VERSION', '1.2.12' );
     20define( 'PPBH_VERSION', '1.2.23' );
    2121define( 'PPBH_FILE', __FILE__ );
    2222define( 'PPBH_DIR', plugin_dir_path( __FILE__ ) );
  • ppeer-glitchpin/tags/1.2.23/public/assets/reporter.js

    r3766335 r3766720  
    78337833  // src/reporter/capture.ts
    78347834  var import_html2canvas = __toESM(require_html2canvas());
     7835
     7836  // src/reporter/capture-styles.ts
     7837  function absoluteUrls(css, base) {
     7838    return css.replace(/url\(\s*(?:"((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)'|((?:\\.|[^)\\])*))\s*\)|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/gi, (token, double, single, bare) => {
     7839      if (double === void 0 && single === void 0 && bare === void 0) return token;
     7840      const value = (double ?? single ?? bare.trim()).replace(/\\([\da-f]{1,6}\s?|\r\n|[\n\r\f]|.)/gi, (_, escape) => {
     7841        if (/^[\da-f]/i.test(escape)) {
     7842          const point = parseInt(escape, 16);
     7843          return point > 0 && point <= 1114111 ? String.fromCodePoint(point) : "\uFFFD";
     7844        }
     7845        return /^[\n\r\f]/.test(escape) ? "" : escape;
     7846      });
     7847      try {
     7848        return `url(${JSON.stringify(new URL(value, base).href)})`;
     7849      } catch {
     7850        return token;
     7851      }
     7852    });
     7853  }
     7854  function stylesheetText(sheet, base) {
     7855    let rules;
     7856    try {
     7857      rules = Array.from(sheet.cssRules);
     7858    } catch {
     7859      return null;
     7860    }
     7861    const parts = [];
     7862    for (const rule of rules) {
     7863      if (rule instanceof CSSImportRule) {
     7864        const href = new URL(rule.href, base).href;
     7865        const imported = rule.styleSheet && stylesheetText(rule.styleSheet, href);
     7866        if (imported !== null) {
     7867          let css = imported;
     7868          if (rule.media.mediaText) css = `@media ${rule.media.mediaText} {${css}}`;
     7869          if (rule.supportsText) css = `@supports (${rule.supportsText}) {${css}}`;
     7870          if (rule.layerName != null) css = `@layer ${rule.layerName} {${css}}`;
     7871          parts.push(css);
     7872          continue;
     7873        }
     7874        return null;
     7875      }
     7876      parts.push(absoluteUrls(rule.cssText, base));
     7877    }
     7878    return parts.join("\n");
     7879  }
     7880  function loadedStyles() {
     7881    const styles = /* @__PURE__ */ new Map();
     7882    document.querySelectorAll('link[rel~="stylesheet" i]').forEach((link) => {
     7883      const entries = styles.get(link.href) ?? [];
     7884      entries.push({
     7885        css: link.sheet ? stylesheetText(link.sheet, link.href) : null,
     7886        disabled: link.disabled || !!link.sheet?.disabled
     7887      });
     7888      styles.set(link.href, entries);
     7889    });
     7890    return async (clone) => {
     7891      clone.querySelectorAll('link[rel~="stylesheet" i]').forEach((link) => {
     7892        let href;
     7893        try {
     7894          href = new URL(link.getAttribute("href") || "", document.baseURI).href;
     7895        } catch {
     7896          return;
     7897        }
     7898        const entry = styles.get(href)?.shift();
     7899        if (!entry) return;
     7900        if (entry.disabled) {
     7901          link.remove();
     7902          return;
     7903        }
     7904        if (entry.css === null) return;
     7905        const style = clone.createElement("style");
     7906        style.media = link.media;
     7907        style.nonce = link.nonce;
     7908        style.textContent = entry.css;
     7909        link.replaceWith(style);
     7910        if (!style.sheet) style.replaceWith(link);
     7911      });
     7912      clone.body.getBoundingClientRect();
     7913      if (clone.fonts) await clone.fonts.ready;
     7914    };
     7915  }
     7916
     7917  // src/reporter/capture.ts
    78357918  async function capturePage() {
    78367919    const width = window.innerWidth;
    78377920    const height = window.innerHeight;
     7921    const restoreStyles = loadedStyles();
    78387922    const canvas = await (0, import_html2canvas.default)(document.documentElement, {
    78397923      x: window.scrollX,
    … …  
    78517935      removeContainer: true,
    78527936      ignoreElements: (element) => element.id === "ppbh-root",
    7853       onclone: (clone) => {
     7937      onclone: async (clone) => {
     7938        await restoreStyles(clone);
    78547939        if (/iPhone OS 15_(0|1)/.test(navigator.userAgent)) {
    78557940          clone.querySelectorAll("*").forEach((element) => {
  • ppeer-glitchpin/tags/1.2.23/readme.txt

    r3766437 r3766720  
    55Tested up to: 7.1
    66Requires PHP: 8.3
    7 Stable tag: 1.2.12
     7Stable tag: 1.2.23
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    8080== Changelog ==
    8181
     82= 1.2.23 =
     83* Preserve loaded page styles when capturing feedback in WordPress Playground.
     84* Keep stylesheet order, imported rules, media conditions, and relative asset URLs in captured screenshots.
     85
    8286= 1.2.12 =
    8387* Fix feedback storage in WordPress Playground with SQLite using transactional row locking instead of MySQL advisory locks.
  • ppeer-glitchpin/trunk/languages/ppeer-glitchpin.pot

    r3766437 r3766720  
    33msgid ""
    44msgstr ""
    5 "Project-Id-Version: GlitchPin - Visual Bug Feedback 1.2.12\n"
     5"Project-Id-Version: GlitchPin - Visual Bug Feedback 1.2.23\n"
    66"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/ppeer-glitchpin\n"
    77"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  • ppeer-glitchpin/trunk/ppeer-glitchpin.php

    r3766437 r3766720  
    33 * Plugin Name: GlitchPin - Visual Bug Feedback
    44 * Description: Collect private, local bug reports with screenshots and page context.
    5  * Version: 1.2.12
     5 * Version: 1.2.23
    66 * Requires at least: 6.4
    77 * Requires PHP: 8.3
    … …  
    1818defined( 'ABSPATH' ) || exit;
    1919
    20 define( 'PPBH_VERSION', '1.2.12' );
     20define( 'PPBH_VERSION', '1.2.23' );
    2121define( 'PPBH_FILE', __FILE__ );
    2222define( 'PPBH_DIR', plugin_dir_path( __FILE__ ) );
  • ppeer-glitchpin/trunk/public/assets/reporter.js

    r3766335 r3766720  
    78337833  // src/reporter/capture.ts
    78347834  var import_html2canvas = __toESM(require_html2canvas());
     7835
     7836  // src/reporter/capture-styles.ts
     7837  function absoluteUrls(css, base) {
     7838    return css.replace(/url\(\s*(?:"((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)'|((?:\\.|[^)\\])*))\s*\)|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'/gi, (token, double, single, bare) => {
     7839      if (double === void 0 && single === void 0 && bare === void 0) return token;
     7840      const value = (double ?? single ?? bare.trim()).replace(/\\([\da-f]{1,6}\s?|\r\n|[\n\r\f]|.)/gi, (_, escape) => {
     7841        if (/^[\da-f]/i.test(escape)) {
     7842          const point = parseInt(escape, 16);
     7843          return point > 0 && point <= 1114111 ? String.fromCodePoint(point) : "\uFFFD";
     7844        }
     7845        return /^[\n\r\f]/.test(escape) ? "" : escape;
     7846      });
     7847      try {
     7848        return `url(${JSON.stringify(new URL(value, base).href)})`;
     7849      } catch {
     7850        return token;
     7851      }
     7852    });
     7853  }
     7854  function stylesheetText(sheet, base) {
     7855    let rules;
     7856    try {
     7857      rules = Array.from(sheet.cssRules);
     7858    } catch {
     7859      return null;
     7860    }
     7861    const parts = [];
     7862    for (const rule of rules) {
     7863      if (rule instanceof CSSImportRule) {
     7864        const href = new URL(rule.href, base).href;
     7865        const imported = rule.styleSheet && stylesheetText(rule.styleSheet, href);
     7866        if (imported !== null) {
     7867          let css = imported;
     7868          if (rule.media.mediaText) css = `@media ${rule.media.mediaText} {${css}}`;
     7869          if (rule.supportsText) css = `@supports (${rule.supportsText}) {${css}}`;
     7870          if (rule.layerName != null) css = `@layer ${rule.layerName} {${css}}`;
     7871          parts.push(css);
     7872          continue;
     7873        }
     7874        return null;
     7875      }
     7876      parts.push(absoluteUrls(rule.cssText, base));
     7877    }
     7878    return parts.join("\n");
     7879  }
     7880  function loadedStyles() {
     7881    const styles = /* @__PURE__ */ new Map();
     7882    document.querySelectorAll('link[rel~="stylesheet" i]').forEach((link) => {
     7883      const entries = styles.get(link.href) ?? [];
     7884      entries.push({
     7885        css: link.sheet ? stylesheetText(link.sheet, link.href) : null,
     7886        disabled: link.disabled || !!link.sheet?.disabled
     7887      });
     7888      styles.set(link.href, entries);
     7889    });
     7890    return async (clone) => {
     7891      clone.querySelectorAll('link[rel~="stylesheet" i]').forEach((link) => {
     7892        let href;
     7893        try {
     7894          href = new URL(link.getAttribute("href") || "", document.baseURI).href;
     7895        } catch {
     7896          return;
     7897        }
     7898        const entry = styles.get(href)?.shift();
     7899        if (!entry) return;
     7900        if (entry.disabled) {
     7901          link.remove();
     7902          return;
     7903        }
     7904        if (entry.css === null) return;
     7905        const style = clone.createElement("style");
     7906        style.media = link.media;
     7907        style.nonce = link.nonce;
     7908        style.textContent = entry.css;
     7909        link.replaceWith(style);
     7910        if (!style.sheet) style.replaceWith(link);
     7911      });
     7912      clone.body.getBoundingClientRect();
     7913      if (clone.fonts) await clone.fonts.ready;
     7914    };
     7915  }
     7916
     7917  // src/reporter/capture.ts
    78357918  async function capturePage() {
    78367919    const width = window.innerWidth;
    78377920    const height = window.innerHeight;
     7921    const restoreStyles = loadedStyles();
    78387922    const canvas = await (0, import_html2canvas.default)(document.documentElement, {
    78397923      x: window.scrollX,
    … …  
    78517935      removeContainer: true,
    78527936      ignoreElements: (element) => element.id === "ppbh-root",
    7853       onclone: (clone) => {
     7937      onclone: async (clone) => {
     7938        await restoreStyles(clone);
    78547939        if (/iPhone OS 15_(0|1)/.test(navigator.userAgent)) {
    78557940          clone.querySelectorAll("*").forEach((element) => {
  • ppeer-glitchpin/trunk/readme.txt

    r3766437 r3766720  
    55Tested up to: 7.1
    66Requires PHP: 8.3
    7 Stable tag: 1.2.12
     7Stable tag: 1.2.23
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    8080== Changelog ==
    8181
     82= 1.2.23 =
     83* Preserve loaded page styles when capturing feedback in WordPress Playground.
     84* Keep stylesheet order, imported rules, media conditions, and relative asset URLs in captured screenshots.
     85
    8286= 1.2.12 =
    8387* Fix feedback storage in WordPress Playground with SQLite using transactional row locking instead of MySQL advisory locks.
Note: See TracChangeset for help on using the changeset viewer.