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

تطوير نسخة الويب لمساعد المنفذ التسلسلي

عرض توضيحي: https://serial.wiki-power.com/
مستودع المشروع: linyuxuanlin/Serial_on_Web

يتم إضافة debugout.js إلى web-serial-terminal لتحقيق وظيفة تسجيل السجلات والتصدير. فيما يلي خطوات مفصلة:

إضافة كود debug.js

// حفظ جميع console.logs
function debugout() {
  var self = this;

  // الخيارات
  self.realTimeLoggingOn = true; // تسجيل السجلات في الوقت الحقيقي (للإرسال إلى console.log)
  self.useTimestamps = false; // إدراج الطابع الزمني قبل كل سجل
  self.useLocalStorage = false; // تخزين الناتج باستخدام window.localStorage() وإضافته باستمرار إلى نفس السجل في كل جلسة
  self.recordLogs = true; // قم بتعيينه على false بعد الانتهاء من عملية التصحيح لتجنب استهلاك الذاكرة
  self.autoTrim = true; // لتجنب استهلاك الذاكرة بشكل لا نهائي
  self.maxLines = 2500; // إذا كان autoTrim مفعلاً ، يتم حفظ هذا العدد من السطور الأخيرة
  self.tailNumLines = 100; // عدد السطور التي ستسترد بواسطة tail()
  self.logFilename = "log.txt"; // اسم ملف السجل الذي يتم تنزيله باستخدام downloadLog()
  self.maxDepth = 25; // الحد الأقصى لعمق التكرار للكائنات المسجلة

  // المتغيرات
  self.depth = 0;
  self.parentSizes = [0];
  self.currentResult = "";
  self.startTime = new Date();
  self.output = "";

  this.version = function () {
    return "0.5.0";
  };

/* طرق المستخدم / this.getLog = function () { var retrievalTime = new Date(); // إذا كان التسجيل مغلقًا ، حتى يعرف المطور لماذا ليس لديه أي سجلات if (!self.recordLogs) { self.log("[debugout.js] تسجيل السجلات مغلق."); } // إذا كنت تستخدم التخزين المحلي ، احصل على القيم if (self.useLocalStorage) { var saved = window.localStorage.getItem("debugout.js"); if (saved) { saved = JSON.parse(saved); self.startTime = new Date(saved.startTime); self.output = saved.log; retrievalTime = new Date(saved.lastLog); } } return ( self.output + "\n---- تم استرداد السجل: " + retrievalTime + " ----\n" + self.formatSessionDuration(self.startTime, retrievalTime) ); }; // يقبل عددًا اختياريًا أو يستخدم القيمة الافتراضية لعدد الأسطر this.tail = function (numLines) { var numLines = numLines || self.tailLines; return self.trimLog(self.getLog(), numLines); }; // يقبل سلسلة للبحث عنها this.search = function (string) { var lines = self.output.split("\n"); var rgx = new RegExp(string); var matched = []; // لا يمكن استخدام Array.prototype.filter() بسيطة هنا // لأننا بحاجة إلى إضافة رقم السطر for (var i = 0; i < lines.length; i++) { var addr = "[" + i + "] "; if (lines[i].match(rgx)) { matched.push(addr + lines[i]); } } var result = matched.join("\n"); if (result.length == 0) result = 'لم يتم العثور على أي شيء لـ "' + string + '".'; return result; }; // يقبل السطر البدء وعدد الأسطر بعد السطر البدء الذي تريده this.getSlice = function (lineNumber, numLines) { var lines = self.output.split("\n"); var segment = lines.slice(lineNumber, lineNumber + numLines); return segment.join("\n"); }; // يقوم بتنزيل السجل على الفور - للاستخدام في متصفح سطح المكتب this.downloadLog = function () { var file = "data:text/plain;charset=utf-8,"; var logFile = self.getLog(); var encoded = encodeURIComponent(logFile); file += encoded; var a = document.createElement("a"); a.href = file; a.target = "_blank"; a.download = self.logFilename; document.body.appendChild(a); a.click(); a.remove(); }; // يقوم بمسح السجل this.clear = function () { var clearTime = new Date(); self.output = "---- تم مسح السجل: " + clearTime + " ----\n"; if (self.useLocalStorage) { // التخزين المحلي var saveObject = { startTime: self.startTime, log: self.output, lastLog: clearTime, }; saveObject = JSON.stringify(saveObject); window.localStorage.setItem("debugout.js", saveObject); } if (self.realTimeLoggingOn) console.log("[debugout.js] مسح()"); }; // يسجل سجل this.log = function (obj) { // سجل في الوقت الحقيقي if (self.realTimeLoggingOn) console.log(obj); // سجل السجل var type = self.determineType(obj); if (type != null && self.recordLogs) { var addition = self.formatType(type, obj); // الطابع الزمني ، المنسق للإيجاز if (self.useTimestamps) { var logTime = new Date(); self.output += self.formatTimestamp(logTime); } self.output += addition; if (self.autoTrim) self.output = self.trimLog(self.output, self.maxLines); // التخزين المحلي if (self.useLocalStorage) { var last = new Date(); var saveObject = { startTime: self.startTime, log: self.output, lastLog: last, }; saveObject = JSON.stringify(saveObject); window.localStorage.setItem("debugout.js", saveObject); } } self.depth = 0; self.parentSizes = [0]; self.currentResult = ""; }; / طرق لبناء السجل */

// مثل typeof ولكن يصنف الكائنات من نوع 'object' // يتم الاحتفاظ بها منفصلة عن formatType() حتى تتمكن من استخدامها في أي وقت تشاء! this.determineType = function (object) { if (object != null) { var typeResult; var type = typeof object; if (type == "object") { var len = object.length; if (len == null) { if (typeof object.getTime == "function") { typeResult = "تاريخ"; } else if (typeof object.test == "function") { typeResult = "تعبير منتظم"; } else { typeResult = "كائن"; } } else { typeResult = "مصفوفة"; } } else { typeResult = type; } return typeResult; } else { return null; } }; // قم بتنسيق النوع وفقًا لذلك ، بشكل متكرر إذا لزم الأمر this.formatType = function (type, obj) { if (self.maxDepth && self.depth >= self.maxDepth) { return "... (تم الوصول إلى الحد الأقصى للعمق)"; } };

    switch (type) {
      case "Object":
        self.currentResult += "{\n";
        self.depth++;
        self.parentSizes.push(self.objectSize(obj));
        var i = 0;
        for (var prop in obj) {
          self.currentResult += self.indentsForDepth(self.depth);
          self.currentResult += prop + ": ";
          var subtype = self.determineType(obj[prop]);
          var subresult = self.formatType(subtype, obj[prop]);
          if (subresult) {
            self.currentResult += subresult;
            if (i != self.parentSizes[self.depth] - 1)
              self.currentResult += ",";
            self.currentResult += "\n";
          } else {
            if (i != self.parentSizes[self.depth] - 1)
              self.currentResult += ",";
            self.currentResult += "\n";
          }
          i++;
        }
        self.depth--;
        self.parentSizes.pop();
        self.currentResult += self.indentsForDepth(self.depth);
        self.currentResult += "}";
        if (self.depth == 0) return self.currentResult;
        break;
      case "Array":
        self.currentResult += "[";
        self.depth++;
        self.parentSizes.push(obj.length);
        for (var i = 0; i < obj.length; i++) {
          var subtype = self.determineType(obj[i]);
          if (subtype == "Object" || subtype == "Array")
            self.currentResult += "\n" + self.indentsForDepth(self.depth);
          var subresult = self.formatType(subtype, obj[i]);
          if (subresult) {
            self.currentResult += subresult;
            if (i != self.parentSizes[self.depth] - 1)
              self.currentResult += ", ";
            if (subtype == "Array") self.currentResult += "\n";
          } else {
            if (i != self.parentSizes[self.depth] - 1)
              self.currentResult += ", ";
            if (subtype != "Object") self.currentResult += "\n";
            else if (i == self.parentSizes[self.depth] - 1)
              self.currentResult += "\n";
          }
        }
        self.depth--;
        self.parentSizes.pop();
        self.currentResult += "]";
        if (self.depth == 0) return self.currentResult;
        break;
      case "function":
        obj += "";
        var lines = obj.split("\n");
        for (var i = 0; i < lines.length; i++) {
          if (lines[i].match(/\}/)) self.depth--;
          self.currentResult += self.indentsForDepth(self.depth);
          if (lines[i].match(/\{/)) self.depth++;
          self.currentResult += lines[i] + "\n";
        }
        return self.currentResult;
        break;
      case "RegExp":
        return "/" + obj.source + "/";
        break;
      case "Date":
      case "string":
        if (self.depth > 0 || obj.length == 0) {
          return '"' + obj + '"';
        } else {
          return obj;
        }
      case "boolean":
        if (obj) return "true";
        else return "false";
      case "number":
        return obj + "";
        break;
    }
  };
  this.indentsForDepth = function (depth) {
    var str = "";
    for (var i = 0; i < depth; i++) {
      str += "\t";
    }
    return str;
  };
  this.trimLog = function (log, maxLines) {
    var lines = log.split("\n");
    if (lines.length > maxLines) {
      lines = lines.slice(lines.length - maxLines);
    }
    return lines.join("\n");
  };
  this.lines = function () {
    return self.output.split("\n").length;
  };
  // calculate testing time
  this.formatSessionDuration = function (startTime, endTime) {
    var msec = endTime - startTime;
    var hh = Math.floor(msec / 1000 / 60 / 60);
    var hrs = ("0" + hh).slice(-2);
    msec -= hh * 1000 * 60 * 60;
    var mm = Math.floor(msec / 1000 / 60);
    var mins = ("0" + mm).slice(-2);
    msec -= mm * 1000 * 60;
    var ss = Math.floor(msec / 1000);
    var secs = ("0" + ss).slice(-2);
    msec -= ss * 1000;
    return "---- مدة الجلسة: " + hrs + ":" + mins + ":" + secs + " ----";
  };
  this.formatTimestamp = function (timestamp) {
    var year = timestamp.getFullYear();
    var date = timestamp.getDate();
    var month = ("0" + (timestamp.getMonth() + 1)).slice(-2);
    var hrs = Number(timestamp.getHours());
    var mins = ("0" + timestamp.getMinutes()).slice(-2);
    var secs = ("0" + timestamp.getSeconds()).slice(-2);
    return (
      "[" +
      year +
      "-" +
      month +
      "-" +
      date +
      " " +
      hrs +
      ":" +
      mins +
      ":" +
      secs +
      "]: "
    );
  };
  this.objectSize = function (obj) {
    var size = 0,
      key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
    return size;
  };

/* بدء / استئناف السجل */ if (self.useLocalStorage) { var saved = window.localStorage.getItem("debugout.js"); if (saved) { saved = JSON.parse(saved); self.output = saved.log; var start = new Date(saved.startTime); var end = new Date(saved.lastLog); self.output += "\n---- نهاية الجلسة: " + saved.lastLog + " ----\n"; self.output += self.formatSessionDuration(start, end); self.output += "\n\n"; } } self.output += "---- بدء الجلسة: " + self.startTime + " ----\n\n"; }

### إضافة زر لتنزيل السجل

بعد البيان `<button id="SerialConnectButton" type="button" disabled>Connect</button>` ، أضف:

```html
<button onclick="bugout.downloadLog();">تنزيل السجل</button>

استدعاء الكائن

أضف في <script>:

var bugout = new debugout();

إخراج السجل

بعد term.write(chunk); ، أضف:

bugout.log(chunk);

المراجع والشكر

عنوان النص: https://wiki-power.com/ يتم حماية هذا المقال بموجب اتفاقية CC BY-NC-SA 4.0، يُرجى ذكر المصدر عند إعادة النشر.

تمت ترجمة هذه المشاركة باستخدام ChatGPT، يرجى تزويدنا بتعليقاتكم إذا كانت هناك أي حذف أو إهمال.