start_controls_section(
'section_codeselector_editor',
array(
'label' => esc_html__( 'Code Editor', 'codeselector' ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
)
);
// Marketincode visual identity header ("code" in white + "Selector." in #25D366). Collapsible.
$this->add_control(
'codeselector_brand_header',
array(
'type' => \Elementor\Controls_Manager::RAW_HTML,
'raw' => '
codeSelector.
v' . esc_html( CODESELECTOR_VERSION ) . '
' . wp_kses_post( __( '1-Click to jump to the HTML line, or Double-Click any text or image to edit it live on canvas.', 'codeselector' ) ) . '
' . esc_html__( '1x Click', 'codeselector' ) . '
' . esc_html__( 'Jump to HTML line', 'codeselector' ) . '
' . esc_html__( '2x Click', 'codeselector' ) . '
' . esc_html__( 'Edit text / img', 'codeselector' ) . '
' . esc_html__( 'Bidirectional Bridge + Live Editing', 'codeselector' ) . '
' . esc_html__( 'READY', 'codeselector' ) . '
',
)
);
// Main CODE control (native Elementor Ace Editor).
$this->add_control(
'source_code',
array(
'label' => esc_html__( 'HTML / CSS Block', 'codeselector' ),
'type' => \Elementor\Controls_Manager::CODE,
'language' => 'html',
'rows' => 28,
'default' => $this->get_default_starter_code(),
'description' => esc_html__( '1-click in preview jumps to the line; double-click edits text and images live.', 'codeselector' ),
'dynamic' => array(
'active' => false,
),
)
);
// Informational notice linking to the extended Pro edition.
$this->add_control(
'codeselector_pro_features_info',
array(
'type' => \Elementor\Controls_Manager::RAW_HTML,
'raw' => '' . sprintf(
/* translators: %s: Upgrade URL */
wp_kses_post( __( 'Looking for CSS auto-scoping or script animations?
Explore codeSelector. Pro →', 'codeselector' ) ),
'https://marketincode.com/codeselector/'
) . '
',
)
);
$this->end_controls_section();
}
/**
* Load default starter template from static asset file.
*
* @return string
*/
private function get_default_starter_code() {
$template_file = CODESELECTOR_PATH . 'assets/starter-template.txt';
if ( ! file_exists( $template_file ) ) {
return '';
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Reading local static starter template file.
$code = file_get_contents( $template_file );
if ( ! is_string( $code ) ) {
return '';
}
$img = esc_url( CODESELECTOR_URL . 'assets/images/placeholder.svg' );
return str_replace( '{{PLACEHOLDER_IMG}}', $img, $code );
}
/**
* Server-side rendering (Frontend and initial Editor load).
* Enqueues sanitized CSS via wp_add_inline_style() and outputs wp_kses() sanitized HTML.
*
* @return void
*/
protected function render() {
$settings = $this->get_settings_for_display();
$raw_code = isset( $settings['source_code'] ) ? $settings['source_code'] : '';
if ( '' === trim( $raw_code ) ) {
return;
}
$widget_id = $this->get_id();
$clean_css = CodeSelector_Sanitizer::extract_sanitized_css( $raw_code );
if ( '' !== $clean_css ) {
$style_handle = 'codeselector-inline-' . sanitize_key( $widget_id );
wp_register_style( $style_handle, false, array(), CODESELECTOR_VERSION );
wp_enqueue_style( $style_handle );
wp_add_inline_style( $style_handle, $clean_css );
}
$this->add_render_attribute(
'wrapper',
array(
'class' => 'codeselector-canvas',
'data-codeselector-id' => $widget_id,
)
);
?>
print_render_attribute_string( 'wrapper' ); ?>>
<#
if ( settings.source_code && settings.source_code.trim() !== '' ) {
var widgetId = view.getID();
var safePreviewCode = settings.source_code
.replace( /^\s*```[a-zA-Z0-9_-]*\r?\n?/, '' )
.replace( /\r?\n?```\s*$/, '' )
.replace( /<(script|iframe|object|embed|applet|foreignobject)\b[^>]*>[\s\S]*?<\/\1>/gi, '' )
.replace( /<(script|iframe|object|embed|applet|foreignobject)\b[^>]*\/?>/gi, '' )
.replace( /\s+on[a-z]+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '' );
view.addRenderAttribute( 'wrapper', {
'class': 'codeselector-canvas',
'data-codeselector-id': widgetId
} );
#>
{{{ safePreviewCode }}}
<# } #>