Commit 96e0fe93 authored by Carsten  Rose's avatar Carsten Rose
Browse files

Bug 7539: Copy to clipboard not reliable. Fixes #7539. Direct content now correctly encoded.

parent 25ed1e23
Pipeline #1255 passed with stage
in 1 minute and 53 seconds
...@@ -37,7 +37,7 @@ require_once(__DIR__ . '/../../core/helper/OnString.php'); ...@@ -37,7 +37,7 @@ require_once(__DIR__ . '/../../core/helper/OnString.php');
class KeyValueStringParser { class KeyValueStringParser {
/** /**
* Builds a string based on kvp array. Concatenatet by the given delimiter. * Builds a string based on kvp array. Concatenate by the given delimiter.
* *
* @param array $keyValueArray * @param array $keyValueArray
* @param string $keyValueDelimiter * @param string $keyValueDelimiter
......
...@@ -206,19 +206,4 @@ class OnString { ...@@ -206,19 +206,4 @@ class OnString {
return $str; return $str;
} }
/**
* Replace character ' and " by the unicode representation. This is useful for JS code, embedded in HTML code.
* <button onclick="new QfqNS.Clipboard({text: 'single tick -\u0027-' });">
*
* @param $str
* @return mixed
*/
public static function replaceByUnicode($str) {
$str = str_replace('"', '\u0022', $str);
$str = str_replace("'", '\u0027', $str);
return ($str);
}
} }
...@@ -514,7 +514,8 @@ class Link { ...@@ -514,7 +514,8 @@ class Link {
$flagArray = array(); $flagArray = array();
// str="u:http://www.example.com|c:i|t:Hello World|q:Do you really want to delete the record 25:warn:yes:no" // str="u:http://www.example.com|c:i|t:Hello World|q:Do you really want to delete the record 25:warn:yes:no"
$param = explode(PARAM_DELIMITER, $str); // $param = explode(PARAM_DELIMITER, $str);
$param = KeyValueStringParser::explodeEscape(PARAM_DELIMITER, $str);
$param = $this->paramPriority($param); $param = $this->paramPriority($param);
...@@ -1458,7 +1459,8 @@ EOF; ...@@ -1458,7 +1459,8 @@ EOF;
// Clipboard Source // Clipboard Source
if ($vars[NAME_COPY_TO_CLIPBOARD] !== '') { if ($vars[NAME_COPY_TO_CLIPBOARD] !== '') {
$jsAction = 'onClick'; $jsAction = 'onClick';
$source = "{text: '" . OnString::replaceByUnicode($vars[NAME_COPY_TO_CLIPBOARD]) . "' }"; // Take care that ' and " are properly escaped
$source = json_encode(["text" => $vars[NAME_COPY_TO_CLIPBOARD]], JSON_HEX_QUOT|JSON_HEX_APOS);
} elseif (isset($vars[NAME_COLLECT_ELEMENTS][0])) { } elseif (isset($vars[NAME_COLLECT_ELEMENTS][0])) {
$jsAction = 'onmousedown'; $jsAction = 'onmousedown';
...@@ -1466,20 +1468,15 @@ EOF; ...@@ -1466,20 +1468,15 @@ EOF;
$tmpUrlParam = array(); $tmpUrlParam = array();
$tmpUrlParam[DOWNLOAD_MODE] = DOWNLOAD_MODE_FILE; $tmpUrlParam[DOWNLOAD_MODE] = DOWNLOAD_MODE_FILE;
$tmpUrlParam[DOWNLOAD_OUTPUT_FORMAT] = DOWNLOAD_OUTPUT_FORMAT_JSON; $tmpUrlParam[DOWNLOAD_OUTPUT_FORMAT] = DOWNLOAD_OUTPUT_FORMAT_JSON;
// $tmpUrlParam[SIP_DOWNLOAD_PARAMETER] = base64_encode(implode(PARAM_DELIMITER, $vars[NAME_COLLECT_ELEMENTS]));
// $vars[NAME_URL_PARAM] = KeyValueStringParser::unparse($tmpUrlParam, '=', '&');
$tmpUrlParam[SIP_DOWNLOAD_PARAMETER] = base64_encode(implode(PARAM_DELIMITER, $vars[NAME_COLLECT_ELEMENTS])); $tmpUrlParam[SIP_DOWNLOAD_PARAMETER] = base64_encode(implode(PARAM_DELIMITER, $vars[NAME_COLLECT_ELEMENTS]));
$urlNParam = KeyValueStringParser::unparse($tmpUrlParam, '=', '&'); $urlNParam = KeyValueStringParser::unparse($tmpUrlParam, '=', '&');
// $vars[NAME_URL] = API_DIR . '/' . API_DOWNLOAD_PHP;
$paramArray = $this->sip->queryStringToSip($urlNParam, RETURN_ARRAY); $paramArray = $this->sip->queryStringToSip($urlNParam, RETURN_ARRAY);
if (Support::findInSet(SYSTEM_SHOW_DEBUG_INFO_YES, $this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM))) { if (Support::findInSet(SYSTEM_SHOW_DEBUG_INFO_YES, $this->store->getVar(SYSTEM_SHOW_DEBUG_INFO, STORE_SYSTEM))) {
$vars[NAME_TOOL_TIP] .= PHP_EOL . PHP_EOL . $this->sip->debugSip($paramArray); $vars[NAME_TOOL_TIP] .= PHP_EOL . PHP_EOL . $this->sip->debugSip($paramArray);
} }
$source = "{uri: '" . API_DIR . '/' . API_DOWNLOAD_PHP . '?s=' . $paramArray[SIP_SIP] . "'}"; $source = json_encode(['uri' => API_DIR . '/' . API_DOWNLOAD_PHP . '?s=' . $paramArray[SIP_SIP] ]);
} else { } else {
throw new UserReportException("Missing content for 'copy to clipboard'", ERROR_MISSING_CONTENT); throw new UserReportException("Missing content for 'copy to clipboard'", ERROR_MISSING_CONTENT);
} }
...@@ -1487,26 +1484,11 @@ EOF; ...@@ -1487,26 +1484,11 @@ EOF;
// Depending on 'text' or 'file' different JS class are necessary. // Depending on 'text' or 'file' different JS class are necessary.
// onClick="new QfqNS.Clipboard({text: 'test clipboard'});"> // onClick="new QfqNS.Clipboard({text: 'test clipboard'});">
// onmousedown="new QfqNS.Clipboard({uri: 'mockData/downloadResponse.json'});"> // onmousedown="new QfqNS.Clipboard({uri: 'mockData/downloadResponse.json'});">
$onClick = "$jsAction=\"new QfqNS.Clipboard($source);\""; $onClick = "$jsAction='new QfqNS.Clipboard($source);'";
// <button class="btn btn-info"
// onClick="new QfqNS.Clipboard({text: 'test clipboard'});">
// Test Clipboard
// </button>
// $vars[NAME_URL] = API_DIR . '/' . API_DOWNLOAD_PHP;
// $vars[NAME_LINK_CLASS_DEFAULT] = NO_CLASS;
// if ($vars[NAME_BOOTSTRAP_BUTTON] == '0') {
// $vars[NAME_EXTRA_CONTENT_WRAP] = '<button type="button" ' . $attributes . $onClick . '>';
// } else {
$vars[NAME_EXTRA_CONTENT_WRAP] = '<button ' . $attributes . $onClick . '>'; $vars[NAME_EXTRA_CONTENT_WRAP] = '<button ' . $attributes . $onClick . '>';
$vars[NAME_BOOTSTRAP_BUTTON] = ''; $vars[NAME_BOOTSTRAP_BUTTON] = '';
// }
return $vars; return $vars;
} }
......
...@@ -1364,27 +1364,28 @@ EOF; ...@@ -1364,27 +1364,28 @@ EOF;
// Single file // Single file
$result = $link->renderLink('d|F:file.pdf'); $result = $link->renderLink('d|F:file.pdf');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZg==" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result); // $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZg==" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result);
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result);
// With download filename // With download filename
$result = $link->renderLink('d:download.pdf|F:file.pdf'); $result = $link->renderLink('d:download.pdf|F:file.pdf');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=download.pdf&_b64_download=RjpmaWxlLnBkZg==" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: download.pdf" data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result); $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: download.pdf" data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result);
// Two files // Two files
$result = $link->renderLink('d|F:file.pdf|F:file2.pdf'); $result = $link->renderLink('d|F:file.pdf|F:file2.pdf');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZnxGOmZpbGUyLnBkZg==" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result); $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result);
// Mode: PDF // Mode: PDF
$result = $link->renderLink('d|F:file.pdf|M:pdf'); $result = $link->renderLink('d|F:file.pdf|M:pdf');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZg==" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result); $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result);
// Download with Tooltip // Download with Tooltip
$result = $link->renderLink('d|F:file.pdf|o:Tooltip'); $result = $link->renderLink('d|F:file.pdf|o:Tooltip');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZg==" class="0" title="Tooltip" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result); $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" title="Tooltip" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span></span></a>', $result);
// Download & Button Text // Download & Button Text
$result = $link->renderLink('d|F:file.pdf|t:Button text'); $result = $link->renderLink('d|F:file.pdf|t:Button text');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZg==" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span> Button text</span></a>', $result); $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" title="Download" ><span class="btn btn-default" data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));"><span class="glyphicon glyphicon-file" ></span> Button text</span></a>', $result);
// Download, r:3 // Download, r:3
$result = $link->renderLink('d|F:file.pdf|r:3'); $result = $link->renderLink('d|F:file.pdf|r:3');
...@@ -1397,7 +1398,7 @@ EOF; ...@@ -1397,7 +1398,7 @@ EOF;
// Single file // Single file
$result = $link->renderLink('d|F:file.pdf|t:DL|b:0'); $result = $link->renderLink('d|F:file.pdf|t:DL|b:0');
$this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?mode=pdf&_exportFilename=&_b64_download=RjpmaWxlLnBkZg==" class="0" ><span data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));">DL</span></a>', $result); $this->assertEquals('<a href="typo3conf/ext/qfq/Source/api/download.php?s=badcaffee1234" class="0" ><span data-toggle="modal" data-target="#qfqModal101" data-title="Download: " data-text="Please wait" data-backdrop="static" data-keyboard="false" onclick="$(\'#qfqModalTitle101\').text($(this).data(\'title\')); $(\'#qfqModalText101\').text($(this).data(\'text\'));">DL</span></a>', $result);
// Single file // Single file
$result = $link->renderLink('d|F:file.pdf|t:DL|b:0|r:3'); $result = $link->renderLink('d|F:file.pdf|t:DL|b:0|r:3');
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment