propertyEditor.js

10.73 KB
12/10/2025 04:24
JS
propertyEditor.js
/**
 * Property Editor Module
 * จัดการการแก้ไขคุณสมบัติของอิลิเมนต์ที่เลือก
 */
(function(global) {
  'use strict';

  /**
   * คลาส PropertyEditor
   * ให้ความสามารถในการแก้ไขคุณสมบัติของอิลิเมนต์ที่เลือก
   */
  class PropertyEditor {
    constructor(editor) {
      this.editor = editor;
      this.selectedElement = null;
      this.propertyInputs = {};
      this.customProperties = {};
    }

    /**
     * เริ่มต้นโมดูลตัวแก้ไขคุณสมบัติ
     */
    init() {
      this.setupEventListeners();
      this.initializePropertyInputs();

      if (this.editor.config.debug) {
        console.log('PropertyEditor เริ่มต้นแล้ว');
      }
    }

    /**
     * เริ่มต้นอินพุตคุณสมบัติ
     */
    initializePropertyInputs() {
      // ค้นหาอินพุตคุณสมบัติทั้งหมดในแผงคุณสมบัติ
      const inputs = document.querySelectorAll('.property-input');

      inputs.forEach(input => {
        const propertyId = input.id;
        this.propertyInputs[propertyId] = input;

        // เพิ่ม event listener สำหรับการเปลี่ยนแปลง
        input.addEventListener('change', (e) => {
          this.handlePropertyChange(propertyId, e.target.value);
        });

        input.addEventListener('input', (e) => {
          this.handlePropertyChange(propertyId, e.target.value);
        });
      });
    }

    /**
     * ตั้งค่า event listeners
     */
    setupEventListeners() {
      // ฟังเหตุการณ์การเลือกอิลิเมนต์
      this.editor.on('element:selected', (data) => {
        this.selectElement(data.element);
      });

      // ฟังเหตุการณ์การเปลี่ยนแปลงโหมดตัวแก้ไข
      this.editor.on('editor:mode-changed', (data) => {
        if (data.mode === 'preview') {
          this.deselectElement();
        }
      });
    }

    /**
     * เลือกอิลิเมนต์
     */
    selectElement(element) {
      this.selectedElement = element;

      // อัปเดตคุณสมบัติในแผง
      this.updatePropertyPanel();

      // แสดงแผงคุณสมบัติ
      this.editor.uiManager.showPanel('property');
    }

    /**
     * ยกเลิกการเลือกอิลิเมนต์
     */
    deselectElement() {
      this.selectedElement = null;

      // รีเซ็ตค่าในแผงคุณสมบัติ
      this.resetPropertyPanel();
    }

    /**
     * อัปเดตแผงคุณสมบัติ
     */
    updatePropertyPanel() {
      if (!this.selectedElement) return;

      // รับค่าคุณสมบัติปัจจุบัน
      const computedStyle = window.getComputedStyle(this.selectedElement);

      // อัปเดตค่าในแผงคุณสมบัติ
      this.updatePropertyInput('text-content', this.selectedElement.textContent);
      this.updatePropertyInput('font-family', computedStyle.fontFamily);
      this.updatePropertyInput('font-size', parseInt(computedStyle.fontSize));
      this.updatePropertyInput('color', this.editor.rgbToHex(computedStyle.color));
      this.updatePropertyInput('background-color', this.editor.rgbToHex(computedStyle.backgroundColor));
      this.updatePropertyInput('background-image', this.extractBackgroundImage(computedStyle.backgroundImage));
      this.updatePropertyInput('padding', parseInt(computedStyle.padding));
      this.updatePropertyInput('margin', parseInt(computedStyle.margin));
      this.updatePropertyInput('display', computedStyle.display);
      this.updatePropertyInput('position', computedStyle.position);

      // อัปเดตคุณสมบัติเฉพาะของอิลิเมนต์
      this.updateElementSpecificProperties();
    }

    /**
     * อัปเดตคุณสมบัติเฉพาะของอิลิเมนต์
     */
    updateElementSpecificProperties() {
      if (!this.selectedElement) return;

      const tagName = this.selectedElement.tagName.toLowerCase();

      switch (tagName) {
        case 'img':
          this.updateImageProperties();
          break;
        case 'a':
          this.updateLinkProperties();
          break;
        case 'button':
          this.updateButtonProperties();
          break;
        case 'input':
        case 'textarea':
          this.updateInputProperties();
          break;
      }
    }

    /**
     * อัปเดตคุณสมบัติรูปภาพ
     */
    updateImageProperties() {
      this.updatePropertyInput('img-src', this.selectedElement.src);
      this.updatePropertyInput('img-alt', this.selectedElement.alt);
      this.updatePropertyInput('img-width', this.selectedElement.width);
      this.updatePropertyInput('img-height', this.selectedElement.height);
    }

    /**
     * อัปเดตคุณสมบัติลิงก์
     */
    updateLinkProperties() {
      this.updatePropertyInput('link-href', this.selectedElement.href);
      this.updatePropertyInput('link-target', this.selectedElement.target);
    }

    /**
     * อัปเดตคุณสมบัติปุ่ม
     */
    updateButtonProperties() {
      this.updatePropertyInput('button-type', this.selectedElement.type);
    }

    /**
     * อัปเดตคุณสมบัติอินพุต
     */
    updateInputProperties() {
      this.updatePropertyInput('input-type', this.selectedElement.type);
      this.updatePropertyInput('input-name', this.selectedElement.name);
      this.updatePropertyInput('input-placeholder', this.selectedElement.placeholder);
      this.updatePropertyInput('input-value', this.selectedElement.value);
    }

    /**
     * อัปเดตอินพุตคุณสมบัติ
     */
    updatePropertyInput(propertyId, value) {
      const input = this.propertyInputs[propertyId];
      if (!input) return;

      // แปลงค่าตามประเภทอินพุต
      if (input.type === 'number') {
        input.value = parseInt(value) || 0;
      } else if (input.type === 'color') {
        input.value = value || '#ffffff';
      } else {
        input.value = value || '';
      }
    }

    /**
     * รีเซ็ตแผงคุณสมบัติ
     */
    resetPropertyPanel() {
      // รีเซ็ตค่าทั้งหมดในแผงคุณสมบัติ
      Object.keys(this.propertyInputs).forEach(propertyId => {
        const input = this.propertyInputs[propertyId];

        if (input.type === 'number') {
          input.value = 0;
        } else if (input.type === 'color') {
          input.value = '#ffffff';
        } else {
          input.value = '';
        }
      });
    }

    /**
     * จัดการการเปลี่ยนแปลงคุณสมบัติ
     */
    handlePropertyChange(propertyId, value) {
      if (!this.selectedElement) return;

      // แปลงค่าตามประเภทอินพุต
      const input = this.propertyInputs[propertyId];
      if (input.type === 'number') {
        value = parseInt(value) || 0;
      }

      // อัปเดตคุณสมบัติอิลิเมนต์
      this.updateElementProperty(propertyId, value);

      // ส่งเหตุการณ์
      this.editor.emit('property:changed', {
        property: propertyId,
        value,
        element: this.selectedElement
      });
    }

    /**
     * อัปเดตคุณสมบัติอิลิเมนต์
     */
    updateElementProperty(propertyId, value) {
      if (!this.selectedElement) return;

      switch (propertyId) {
        case 'text-content':
          this.selectedElement.textContent = value;
          break;
        case 'font-family':
          this.selectedElement.style.fontFamily = value;
          break;
        case 'font-size':
          this.selectedElement.style.fontSize = value + 'px';
          break;
        case 'color':
          this.selectedElement.style.color = value;
          break;
        case 'background-color':
          this.selectedElement.style.backgroundColor = value;
          break;
        case 'background-image':
          if (value) {
            this.selectedElement.style.backgroundImage = `url(${value})`;
          } else {
            this.selectedElement.style.backgroundImage = '';
          }
          break;
        case 'padding':
          this.selectedElement.style.padding = value + 'px';
          break;
        case 'margin':
          this.selectedElement.style.margin = value + 'px';
          break;
        case 'display':
          this.selectedElement.style.display = value;
          break;
        case 'position':
          this.selectedElement.style.position = value;
          break;
        case 'img-src':
          this.selectedElement.src = value;
          break;
        case 'img-alt':
          this.selectedElement.alt = value;
          break;
        case 'img-width':
          this.selectedElement.width = value;
          break;
        case 'img-height':
          this.selectedElement.height = value;
          break;
        case 'link-href':
          this.selectedElement.href = value;
          break;
        case 'link-target':
          this.selectedElement.target = value;
          break;
        case 'button-type':
          this.selectedElement.type = value;
          break;
        case 'input-type':
          this.selectedElement.type = value;
          break;
        case 'input-name':
          this.selectedElement.name = value;
          break;
        case 'input-placeholder':
          this.selectedElement.placeholder = value;
          break;
        case 'input-value':
          this.selectedElement.value = value;
          break;
      }
    }

    /**
     * แยกรูปภาพพื้นหลังจากค่า CSS
     */
    extractBackgroundImage(backgroundImage) {
      if (!backgroundImage || backgroundImage === 'none') {
        return '';
      }

      // แยก URL จากค่า background-image
      const match = backgroundImage.match(/url\(["']?(.*?)["']?\)/);
      return match ? match[1] : '';
    }
  }

  // เปิดเผยคลาส PropertyEditor ทั่วโลก
  global.PropertyEditor = PropertyEditor;

})(typeof window !== 'undefined' ? window : this);