From 84041c20999a5bc32bfdd13612543fff0d738c97 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bartosz=20Dziewo=C5=84ski?= <matma.rex@gmail.com>
Date: Tue, 1 Dec 2015 21:11:43 +0100
Subject: [PATCH] Attribute-aware StripState

Change-Id: Id37d6e8d60bab9d787cc6dcb7606ce49f51a1c83
---
 includes/parser/Parser.php     |  4 ++++
 includes/parser/StripState.php | 28 ++++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/includes/parser/Parser.php b/includes/parser/Parser.php
index cfbf0b4..6d4f7f5 100644
--- a/includes/parser/Parser.php
+++ b/includes/parser/Parser.php
@@ -1288,6 +1288,8 @@ class Parser {
 	 * @return string
 	 */
 	private function internalParseHalfParsed( $text, $isMain = true, $linestart = true ) {
+		$this->mStripState->attrAware = true;
+		
 		$text = $this->mStripState->unstripGeneral( $text );
 
 		if ( $isMain ) {
@@ -1372,6 +1374,8 @@ class Parser {
 		if ( $isMain ) {
 			Hooks::run( 'ParserAfterTidy', array( &$this, &$text ) );
 		}
+		
+		$this->mStripState->attrAware = false;
 
 		return $text;
 	}
diff --git a/includes/parser/StripState.php b/includes/parser/StripState.php
index b11dc8c..0859cd2 100644
--- a/includes/parser/StripState.php
+++ b/includes/parser/StripState.php
@@ -33,6 +33,8 @@ class StripState {
 	protected $tempType, $tempMergePrefix;
 	protected $circularRefGuard;
 	protected $recursionLevel = 0;
+	
+	public $attrAware = false;
 
 	const UNSTRIP_RECURSION_LIMIT = 20;
 
@@ -121,10 +123,36 @@ class StripState {
 		if ( !count( $this->data[$type] ) ) {
 			return $text;
 		}
+		if ( !$text ) {
+			return $text;
+		}
 
 		$oldType = $this->tempType;
 		$this->tempType = $type;
+		
+		// var_dump($text);
+		
+		if ( $this->attrAware ) {
+			// Step 1. Replace strip markers inside attributes, treating their values as plain text.
+			$dom = new DomDocument;
+			$dom->loadHTML( "<?xml encoding='UTF-8'>$text" );
+			foreach ($dom->childNodes as $item) {
+				if ($item->nodeType == XML_PI_NODE) {
+					$dom->removeChild($item); // remove hack
+				}
+			}
+			$dom->encoding = 'UTF-8'; // insert proper
+			
+			$xpath = new DOMXPath( $dom );
+			foreach ( $xpath->query( '//@*' ) as $attrNode ) {
+				$attrNode->value = preg_replace_callback( $this->regex, array( $this, 'unstripCallback' ), $attrNode->value );
+			}
+			$text = preg_replace('/^<!DOCTYPE.+?>/', '', str_replace( array('<html>', '</html>', '<body>', '</body>'), array('', '', '', ''), $dom->saveHTML()));
+		}
+
+		// Step 2. Replace strip markers inside tag content, treating their values as HTML.
 		$text = preg_replace_callback( $this->regex, array( $this, 'unstripCallback' ), $text );
+
 		$this->tempType = $oldType;
 		return $text;
 	}
-- 
1.9.5.msysgit.0

