Play returning bad request if I use parse.json in Action Composition - playframework-2.6

I have this Action. It works fine
def newQuestion = silhouette.SecuredAction.async /*(parse.json)*/ {
implicit request => {
println("got request with body:" + request.body)
println("got content header headers "+request.request.headers.get("Content-Type"))
val body:AnyContent = request.body
...
}
I have tested it with the following unit test case
"newQuestion" should {
"should return error if the size of the body in the request is more than the maximum allowed size" in {
val sizeConfig = Map("maxAllowedBodySize"-> 10)
val maxBodySizeConfig = Map("codingJedi" -> sizeConfig )
val newConfiguration = Configuration.from(maxBodySizeConfig)
val testEnv = new QuestionsControllerSpecTestEnv(Some(newConfiguration),components)
val body =
s"""
|{
| "practice-question":{
| "description": "some description",
| "hints": ["hint1","hint2"],
| "image": ["image1 data","image2 data","image3 data"],
| "success-test": "success test",
| "fail-test": "fail test",
| "tags": ["${testEnv.tag}","${testEnv.tag}"],
| "title":"some title",
| "answer": "some answer",
| "references":["ref1","ref2"]
| }
|}
""".stripMargin
val jsonBody = Json.parse(body)
println("jsBody is "+jsonBody)
val request = new FakeRequest(FakeRequest("POST","ws/questions/new-question")).withHeaders(CONTENT_TYPE -> "application/json").withAuthenticator(testEnv.testEnv.loginInfo)(testEnv.testEnv.fakeEnv).withBody(AnyContentAsJson(jsonBody))
println("outgoing request is "+request)
println("headers "+request.headers)
println("body "+request.body)
val response = testEnv.questionsController.newQuestion(request)
val responseBody = contentAsJson(response) println(s"received response body ${responseBody}")
val result = (responseBody \ "result").get.as[String]
val additionalInfo = (responseBody \ "additional-info").get.as[String]
result mustBe "error"
additionalInfo mustBe components.messagesApi("error.entityTooLarge")(components.langs.availables(0))
}
}
But when I try to add parse.json to the Action
def newQuestion = silhouette.SecuredAction.async (parse.json) {...}
The test case fails because Play returns Bad Request
Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: <!DOCTYPE html>
<html lang="en">
<head>
<title>Bad Request</title>
<style>
html, body, pre {
margin: 0;
padding: 0;
font-family: Monaco, 'Lucida Console', monospace;
background: #ECECEC;
}
h1 {
margin: 0;
background: #AD632A;
padding: 20px 45px;
color: #fff;
text-shadow: 1px 1px 1px rgba(0,0,0,.3);
border-bottom: 1px solid #9F5805;
font-size: 28px;
}
p#detail {
margin: 0;
padding: 15px 45px;
background: #F6A960;
border-top: 4px solid #D29052;
color: #733512;
text-shadow: 1px 1px 1px rgba(255,255,255,.3);
font-size: 14px;
border-bottom: 1px solid #BA7F5B;
}
</style>
</head>
<body>
<h1>Bad Request</h1>
<p id="detail">
For request 'POST ws/questions/new-question' [Invalid Json: No content to map due to end-of-input
at [Source: akka.util.ByteIterator$ByteArrayIterator$$anon$1#37af24cb; line: 1, column: 0]]
</p>
</body>
</html>
; line: 1, column: 2]
com.fasterxml.jackson.core.JsonParseException: Unexpected character ('<' (code 60)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: <!DOCTYPE html>
<html lang="en">
<head>
<title>Bad Request</title>
<style>
html, body, pre {
margin: 0;
padding: 0;
font-family: Monaco, 'Lucida Console', monospace;
background: #ECECEC;
}
h1 {
margin: 0;
background: #AD632A;
padding: 20px 45px;
color: #fff;
text-shadow: 1px 1px 1px rgba(0,0,0,.3);
border-bottom: 1px solid #9F5805;
font-size: 28px;
}
p#detail {
margin: 0;
padding: 15px 45px;
background: #F6A960;
border-top: 4px solid #D29052;
color: #733512;
text-shadow: 1px 1px 1px rgba(255,255,255,.3);
font-size: 14px;
border-bottom: 1px solid #BA7F5B;
}
</style>
</head>
<body>
<h1>Bad Request</h1>
<p id="detail">
For request 'POST ws/questions/new-question' [Invalid Json: No content to map due to end-of-input
at [Source: akka.util.ByteIterator$ByteArrayIterator$$anon$1#37af24cb; line: 1, column: 0]]
</p>
</body>
</html>
; line: 1, column: 2]
The json I am sending looks ok.
{"practice-question":{"description":"some description","hints":["hint1","hint2"],"image":["image1 data","image2 data","image3 data"],"success-test":"success test","fail-test":"fail test","tags":["coding-javascript-form","coding-javascript-form"],"title":"some title","answer":"some answer","references":["ref1","ref2"]}}

Related

The script is not output properly

can someone please help me with this? The problem is explained in the video.
https://www.loom.com/share/dba701f22d1c42d38617d9b835d713e4
Here is what I am trying to do, on the input field we will add a youtube video URL and when clicked on the Generate Embed Code button it should output the embed code inside the text aria, do you know why its not working?
<div class="youtube-iframe-generator">
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed&display=swap" rel="stylesheet">
<script>
window.onload = setup;
function setup() {
document.getElementById("button").addEventListener("click", go);
document.getElementById("copy-button").addEventListener("click", copy);
}
function setStatus(status, error = false) {
var helpText = document.getElementById("help-text");
helpText.innerText = status;
if (error) {
helpText.style.color = "darkred";
} else {
helpText.style.color = "#227300";
}
}
function go() {
var videoUrl = document.getElementById("input").value;
var videoIdExtractor = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i;
var result = videoIdExtractor.exec(videoUrl);
var EmbedCode = document.getElementById("EmbedCode");
var copyButton = document.getElementById("copy-button");
if (!result) {
EmbedCode.innerHTML = "";
copyButton.disabled = true;
setStatus("Error: Invalid YouTube URL", true);
return;
}
var videoId = result[1];
var finalLink = "https://www.youtube.com/embed/" + videoId;
var imgLink = "https://img.youtube.com/vi/"+videoId+"/maxresdefault.jpg";
var iframe = '<iframe class="youtube-iframe" srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{position: absolute;content: '\f04b';top: 50%;left: 50%;background-color: #6c6cfe;width: 68px;height: 44px;margin-left: -34px;margin-top: -24px;font-size: 30px;color: #fff;text-align: center;line-height: 43px;z-index: 5;border-radius: 6px;}a{display:block;height:100%;}</style><img src="'+imgLink+'" alt="Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition"><span>▶</span>" frameborder="0" style="aspect-ratio: 16 / 9; width: 100%;" allow="accelerometer; autoplay; encrypted-media; gyroscope;" allowfullscreen></iframe>';
EmbedCode.disabled = false;
copyButton.disabled = false;
EmbedCode.value = iframe;
setStatus("Success! Click the 'Copy' button to copy the embed code.");
}
function copy() {
var EmbedCode = document.getElementById("EmbedCode");
EmbedCode.select();
document.execCommand("copy");
setStatus("Embed code copied to clipboard!");
}
}
</script>
<div class="title">Enter your Youtube URL: <span class="sub">(Scroll down for instructions)</span>
<style>
.youtube-iframe-generator {
font-family: 'Roboto Condensed', sans-serif;
width:96.9%;
}
.title {
font-size: 1.6em;
margin: 15px 0 10px;
}
.sub {
font-size: 0.5em;
color: #444;
vertical-align: middle;
}
#copy-button,
#button {
display: block;
font-family: 'Roboto Condensed', sans-serif;
font-size: 1.2em;
padding: 10px 18px;
margin: 15px auto;
border: none;
border-radius: 3px;
background: #598cff;
color: #ffffff;
cursor: pointer;
box-shadow: 0 2px 3px 0px #b5b5b5;
transition: background 200ms;
}
#copy-button:hover,
#button:hover {
background: #6b99ff;
}
#copy-button:active,
#button:active {
background: #598cff;
box-shadow: 0 2px 3px -1px #b5b5b5;
}
#input{
font-size: 1.1em;
display: block;
width: 100%;
padding: 10px;
border: 1px solid #b5b5b5;
border-radius: 3px;
}
#EmbedCode {
font-size: 1.1em;
display: block;
width: 100%;
padding: 10px;
border: 1px solid #b5b5b5;
border-radius: 3px;
resize: vertical;
overflow: auto;
}
#help-text {
font-weight: 600;
margin: 10px;
}
</style>
</div>
<input id="input" type="text" placeholder="https://www.youtube.com/watch?v=h4iRMtQBGAk">
<button id="button">Generate Embed Code</button>
<div class="title">Embed Code:</div>
<textarea id="EmbedCode" type="text" readonly="" disabled=""></textarea>
<button id="copy-button" disabled> <i class="fa-regular fa-clipboard"></i> Copy Embed Code</button>
<div id="help-text"></div>
</div>

Webview render issue on iOS [Testflight]

I'm trying to render a webview in my flutter project.
It's working perfectly for Android in debug and release modes and on iOS in debug mode as well.
However if I upload a build to Testflight, it does not work for some reason.
I've been working with the same code from the past few months and not had an issue with Flutter v1.
I'm attaching a code snippet below. Any help is appreciated.
Snippet:
return Container(
width: size.width,
height: size.height,
child: WebView(
key: UniqueKey(),
initialUrl: renderHTML(width, content!),
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: <JavascriptChannel>[
JavascriptChannel(
name: 'GetImgSrc',
onMessageReceived: (JavascriptMessage msg) {
print('Stef Method Channel ${msg.message}');
Navigator.of(context)
.pushNamed(PhotoViewer.route, arguments: msg.message);
}),
].toSet(),
navigationDelegate: (request) => NewsArticleController()
.navigationDelegate(request, content!, width),
),
);
renderHtml(width, content) {
return Uri.dataFromString(body, mimeType: 'text/html', encoding: Encoding.getByName('utf-8')).toString();
}
Html Snippet:
String body = '''
<html>
<head>
<meta name='viewport' content='initial-scale = 1.0, width=device-width'/>
<style>
html {
width: ${width}px;
}
body {
margin-left: 8px;
margin-right: 8px;
margin-top: 0px;
margin-bottom: 0px;
background-color: #F6F6F6;
}
em {
font-style: italic;
}
.title {
padding: 0 20px;
font-family: Georgia,Times,Times New Roman,serif;
font-size: 20px;
font-weight: 600;
letter-spacing: 1px;
line-height: 32px;
color:#3D3D3D;
}
.meta-desc {
margin: 8px 0;
font-size: 16px;
text-align: left;
color: #000000;
font-family: Georgia,Times,Times New Roman,serif;
font-weight: 400;
line-height: 24px;
letter-spacing: 1px;
}
.meta-data {
padding: 12px 0 8px 20px;
color:#818181;
font-size: 12px;
line-height: 20px;
font-family: Georgia,Times,Times New Roman,serif;
}
.hero-img img {
margin-left: -8px;
width: ${double.parse(width)}px;
height: auto;
}
.body-content {
padding: 0 20px;
}
.body-content div, .body-content p, .body-content span {
padding: 0 !important;
margin-bottom: 15px !important;
font-size: 20px;
text-align: left;
color: #000000;
font-family: Georgia,Times,Times New Roman,serif;
font-weight: 400;
line-height: 31px;
}
.body-content img {
width: 100%;
height: auto;
margin: auto;
}
a {
color: #F50057;
text-decoration: none;
font-weight: bold;
}
.yt-iframe {
width: ${double.parse(width) - 16}px;
min-height: 200px;
}
iframe.instagram-media {
margin: 0 auto 10px !important;
/* width: ${double.parse(width) - 16}px !important; */
}
iframe {
margin: 0 8px 10px -8px !important;
width: 100% !important;
}
</style>
</head>
<body>
<div class="hero-img cls-image">
<img src="${content.images?.url}">
</div>
<div style="text-align: end; padding: 16px 20px 8px 0; font-size:12px; color:#818181;">${content.postDateStr}</div>
<div class="title">
${content.title}
</div>
<!--<div class="meta-desc">
${content.metaTagDescription}
</div>-->
<div class="meta-data">
By <span>${content.user}</span>
</div>
<div class="body-content">
$body
</div>
</body>
<script>
var elements = document.getElementsByClassName("instagram-media");
setTimeout(function(){
for (var i = 0; i < elements.length; i++) {
elements[i].style.width=('0px');
console.log('initial width: ' + elements[i].style.width);
elements[i].style.width=('${double.parse(width) - 16}px');
console.log('final width: ' + elements[i].style.width);
}
console.log(elements);
}, 1000);
var images = document.getElementsByClassName("cls-image");
var myFunction = function(event) {
GetImgSrc.postMessage(event.target.src);
};
for (var i = 0; i < images.length; i++) {
images[i].addEventListener('click', myFunction, false);
}
</script>
</html>
''';
Flutter version: Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-US
webview_flutter version: 2.0.9
You may need to do more setup for the WebView to work with IOS build - if you're using this package I would suggest taking a look at this and adding in suggested info to your info.plist
https://inappwebview.dev/docs/get-started/setup-ios/

creating turnjs instance before add any pages

I want to add dynamic pages from pdf from page one without cover page. But, I could not create turnjs instance without page inside(cover page that has been hardcoded in html). It output error:
Uncaught (in promise) b {name: "TurnJsError", message: "The page 1 does not exist"}
But, we could not use addpages method of turnjs without declare turnjs instance. How to achieve this?
Currently, I hardcoded cover page in html $('#book').
<div id="book">
<div class="cover">
<h1>Cover</h1>
</div>
</div>
Then, I create turnjs instance as follow:
$('#book').turn({
page: 1,
autoCenter: true,
});
Then, I remove cover page by:
$("#book").turn("removePage", 1);
After that, I start adding pages from pdf. So, it meets my requirement.
Complete code
<?php
ob_start();
require_once('plugin/tcpdf/tcpdf.php');
$pdf = new TCPDF();
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$html_p1 = 'Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters, between two or more users of mobile devices, desktops/laptops, or other type of compatible computer. Text messages may be sent over a cellular network, or may also be sent via an Internet connection';
//echo $html;
$pdf->writeHTML($html_p1, true, 0, true, 0);
$pdf->AddPage();
$html_p2 = 'A telephone call is a connection over a telephone network between the called party and the calling party.';
$pdf->writeHTML($html_p2, true, 0, true, 0);
$pdf->AddPage();
$html_p3 = 'On the Internet, # (pronounced "at" or "at sign" or "address sign") is the symbol in an e-mail address that separates the name of the user from the users Internet address, as in this hypothetical e-mail address example: msmuffet#tuffet.org. In business, # is a symbol meaning "at" or "each."';
$pdf->writeHTML($html_p3, true, 0, true, 0);
$base64PdfString = $pdf->Output('', 'E');
$base64PdfArray = explode("\r\n", $base64PdfString);
$base64 = '';
for($i = 5; $i < count($base64PdfArray); $i++){
$base64 .= $base64PdfArray[$i];
}
?>
<!doctype html>
<html>
<head>
<style type="text/css">
body
{
background: #ccc;
}
#book
{
width: 800px;
height: 500px;
}
#book .turn-page
{
background-color: white;
}
#book .cover
{
background: #333;
}
#book .cover h1
{
color: white;
text-align: center;
font-size: 50px;
line-height: 500px;
margin: 0px;
}
#book .loader
{
background-image: url(loader.gif);
width: 24px;
height: 24px;
display: block;
position: absolute;
top: 238px;
left: 188px;
}
#book .data
{
text-align: center;
font-size: 40px;
color: #999;
line-height: 500px;
}
#controls
{
width: 800px;
text-align: center;
margin: 20px 0px;
font: 30px arial;
}
#controls input, #controls label
{
font: 30px arial;
}
#book .odd
{
background-image: -webkit-linear-gradient(left, #FFF 95%, #ddd 100%);
background-image: -moz-linear-gradient(left, #FFF 95%, #ddd 100%);
background-image: -o-linear-gradient(left, #FFF 95%, #ddd 100%);
background-image: -ms-linear-gradient(left, #FFF 95%, #ddd 100%);
}
#book .even
{
background-image: -webkit-linear-gradient(right, #FFF 95%, #ddd 100%);
background-image: -moz-linear-gradient(right, #FFF 95%, #ddd 100%);
background-image: -o-linear-gradient(right, #FFF 95%, #ddd 100%);
background-image: -ms-linear-gradient(right, #FFF 95%, #ddd 100%);
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="plugin/turnjs4/lib/turn.min.js"></script>
<script type="text/javascript" src="plugin/pdfjs_ex/pdf.js"></script>
<script>
const b64toBlob = (b64Data, contentType='', sliceSize=512) =>
{
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize)
{
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++)
{
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function addPage(page, book, pdf_doc)
{
if (!book.turn('hasPage', page))
{
var element = $('<div />', {'class': 'page '+((page%2==0) ? 'odd' : 'even'), 'id': 'page-'+page}).html('<i class="loader"></i>');
book.turn('addPage', element, page);
pdf_doc.getPage((page)).then(function(p)
{
var scale = 1;
var viewport = p.getViewport(scale);
var pag1 =document.createElement('canvas');
pag1.id ='Pg_1';
var context1 =pag1.getContext('2d');
pag1.height =viewport.height;
pag1.width =viewport.width;
var renderContext =
{
canvasContext: context1,
viewport: viewport
};
p.render(renderContext).then(function()
{
pag1.toBlob(function(blob)
{
var burl =URL.createObjectURL(blob);
setTimeout(function()
{
element.html('<div style="background-image:url('+burl+'); width: 400px; height: 500px; background-size: cover;"></div><div style="top: 0px; left: 0px; overflow: hidden; z-index: 1; width: 461px; height: 600px;"></div>');
}, 1000);
})
})
})
}
}
</script>
</head>
<body>
<div id="book">
<div class="cover">
<h1>
Cover
</h1>
</div>
</div>
<script type="text/javascript">
$(window).ready(function()
{
const contentType ='application/pdf';
const b64Data ='<?php echo $base64;?>';
const blob =b64toBlob(b64Data, contentType);
const blobUrl =URL.createObjectURL(blob);
PDFJS.getDocument({ url: blobUrl }).then(function(pdf_doc)
{
__PDF_DOC = pdf_doc;
__TOTAL_PAGES = __PDF_DOC.numPages;
$('#book').turn({
page: 1,
autoCenter: true,
});
var list = [];
for (var i = 1; i <= __TOTAL_PAGES; i++)
{
list.push(i);
}
$("#book").turn("removePage", 1);
for (page = 0; page<list.length; page++)
addPage(list[page], $("#book"),pdf_doc);
})
});
$(window).bind('keydown', function(e)
{
if (e.target && e.target.tagName.toLowerCase()!='input')
if (e.keyCode==37)
$('#book').turn('previous');
else if (e.keyCode==39)
$('#book').turn('next');
});
</script>
</body>
</html>
But, I still want to know how to create turnjs instance with no pages and display as flipbook after adding all pages.
Most probably you are missing 1 line, which is to append the element you created inside addpage() funciton,
you should use
book.append(customDiv);
//OR you can write same thing as:
$('#book').append(element);
// So your Code mus be:
<?php
ob_start();
require_once('plugin/tcpdf/tcpdf.php');
$pdf = new TCPDF();
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->AddPage();
$html_p1 = 'Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters, between two or more users of mobile devices, desktops/laptops, or other type of compatible computer. Text messages may be sent over a cellular network, or may also be sent via an Internet connection';
//echo $html;
$pdf->writeHTML($html_p1, true, 0, true, 0);
$pdf->AddPage();
$html_p2 = 'A telephone call is a connection over a telephone network between the called party and the calling party.';
$pdf->writeHTML($html_p2, true, 0, true, 0);
$pdf->AddPage();
$html_p3 = 'On the Internet, # (pronounced "at" or "at sign" or "address sign") is the symbol in an e-mail address that separates the name of the user from the users Internet address, as in this hypothetical e-mail address example: msmuffet#tuffet.org. In business, # is a symbol meaning "at" or "each."';
$pdf->writeHTML($html_p3, true, 0, true, 0);
$base64PdfString = $pdf->Output('', 'E');
$base64PdfArray = explode("\r\n", $base64PdfString);
$base64 = '';
for($i = 5; $i < count($base64PdfArray); $i++){
$base64 .= $base64PdfArray[$i];
}
?>
<!doctype html>
<html>
<head>
<style type="text/css">
body
{
background: #ccc;
}
#book
{
width: 800px;
height: 500px;
}
#book .turn-page
{
background-color: white;
}
#book .cover
{
background: #333;
}
#book .cover h1
{
color: white;
text-align: center;
font-size: 50px;
line-height: 500px;
margin: 0px;
}
#book .loader
{
background-image: url(loader.gif);
width: 24px;
height: 24px;
display: block;
position: absolute;
top: 238px;
left: 188px;
}
#book .data
{
text-align: center;
font-size: 40px;
color: #999;
line-height: 500px;
}
#controls
{
width: 800px;
text-align: center;
margin: 20px 0px;
font: 30px arial;
}
#controls input, #controls label
{
font: 30px arial;
}
#book .odd
{
background-image: -webkit-linear-gradient(left, #FFF 95%, #ddd 100%);
background-image: -moz-linear-gradient(left, #FFF 95%, #ddd 100%);
background-image: -o-linear-gradient(left, #FFF 95%, #ddd 100%);
background-image: -ms-linear-gradient(left, #FFF 95%, #ddd 100%);
}
#book .even
{
background-image: -webkit-linear-gradient(right, #FFF 95%, #ddd 100%);
background-image: -moz-linear-gradient(right, #FFF 95%, #ddd 100%);
background-image: -o-linear-gradient(right, #FFF 95%, #ddd 100%);
background-image: -ms-linear-gradient(right, #FFF 95%, #ddd 100%);
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="plugin/turnjs4/lib/turn.min.js"></script>
<script type="text/javascript" src="plugin/pdfjs_ex/pdf.js"></script>
<script>
const b64toBlob = (b64Data, contentType='', sliceSize=512) =>
{
const byteCharacters = atob(b64Data);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize)
{
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++)
{
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
function addPage(page, book, pdf_doc)
{
if (!book.turn('hasPage', page))
{
var element = $('<div />', {'class': 'page '+((page%2==0) ? 'odd' : 'even'), 'id': 'page-'+page}).html('<i class="loader"></i>');
book.turn('addPage', element, page);
pdf_doc.getPage((page)).then(function(p)
{
var scale = 1;
var viewport = p.getViewport(scale);
var pag1 =document.createElement('canvas');
pag1.id ='Pg_1';
var context1 =pag1.getContext('2d');
pag1.height =viewport.height;
pag1.width =viewport.width;
var renderContext =
{
canvasContext: context1,
viewport: viewport
};
p.render(renderContext).then(function()
{
pag1.toBlob(function(blob)
{
var burl =URL.createObjectURL(blob);
setTimeout(function()
{
element.html('<div style="background-image:url('+burl+'); width: 400px; height: 500px; background-size: cover;"></div><div style="top: 0px; left: 0px; overflow: hidden; z-index: 1; width: 461px; height: 600px;"></div>');
book.append(element);
}, 1000);
})
})
})
}
}
</script>
</head>
<body>
<div id="book">
<div class="cover">
<h1>
Cover
</h1>
</div>
</div>
<script type="text/javascript">
$(window).ready(function()
{
const contentType ='application/pdf';
const b64Data ='<?php echo $base64;?>';
const blob =b64toBlob(b64Data, contentType);
const blobUrl =URL.createObjectURL(blob);
PDFJS.getDocument({ url: blobUrl }).then(function(pdf_doc)
{
__PDF_DOC = pdf_doc;
__TOTAL_PAGES = __PDF_DOC.numPages;
$('#book').turn({
page: 1,
autoCenter: true,
});
var list = [];
for (var i = 1; i <= __TOTAL_PAGES; i++)
{
list.push(i);
}
$("#book").turn("removePage", 1);
for (page = 0; page<list.length; page++)
addPage(list[page], $("#book"),pdf_doc);
})
});
$(window).bind('keydown', function(e)
{
if (e.target && e.target.tagName.toLowerCase()!='input')
if (e.keyCode==37)
$('#book').turn('previous');
else if (e.keyCode==39)
$('#book').turn('next');
});
</script>
</body>
</html>

How to handle IF statement in AMP and .NET

#using App
#using Helpers
#model App.Model.Cache
#{
ViewBag.Title = #Model.Title;
Layout = null;
}
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1">
<style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}#-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}#keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-social-share" src="https://cdn.ampproject.org/v0/amp-social-share-0.1.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
<script async custom-element="amp-ad" src="https://cdn.ampproject.org/v0/amp-ad-0.1.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato"/>
#if (!Model.IsBookmark)
{
<link rel="canonical" href="#(Model.CanonicalUrl())"/>
}
else
{
<link rel="canonical" href="#Model.BookmarkURL"/>
}
<style amp-custom>
body {font-family:Lato, Arial;}
.related {
background-color: #f5f5f5;
display: block;
clear: both;
height: 64px;
margin-bottom: 14px;
}
.related > span {
font-size: 16px;
font-weight: 400;
vertical-align: middle;
margin: 8px;
line-height: 1.2em;
height: 64px;
}
.related:hover {
background-color: #ccc;
}
.related-recipes a {
text-decoration: none;
color: #444;
}
.related-image {
width: 64px;
height: 64px;
float: left;
}
.related-text {
display: inline;
vertical-align: middle;
color: #111;
position: relative;
top: 1.2em;
left: .9em;
text-overflow: clip;
word-break: break-all;
word-wrap: break-word;
}
amp-carousel amp-img > img {
object-fit: contain;
}
amp-carousel figcaption {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 8px;
background: rgba(0, 0, 0, 0.6); /* translucent black */
color: #ddd;
font-size: smaller;
max-height: 30%;
}
amp-carousel .review {
width: 25em;
vertical-align: top;
overflow: auto;
margin: 0;
padding: 16px;
height: 80%; /* TODO easy way to ensure the bottom shadow is visible */
white-space: normal; /* the enclosing div generated by amp-carousel sets it to nowrap */
}
amp-carousel .review:nth-child(even) {
background: #FFFFFF
}
amp-carousel .review:nth-child(odd) {
background: #94C2F9
}
amp-carousel .review h1 {
font-size: larger;
padding: 0;
}
amp-carousel .review p {
padding: 0;
}
amp-carousel .review address:before {
content: '-- ';
}
ul, ol {
padding: 0 16px;
}
/* Unicode-based stars and half-star credit: amoniker, https://coderwall.com/p/iml9ka/star-ratings-in-css-utf8 */
.star-icon {
color: #ddd;
font-size: 34px;
position: relative;
}
.star-icon.full:before {
color: #FDE16D;
content: '\2605'; /* Full star in UTF8 */
position: absolute;
left: 0;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.7);
}
.star-icon.half:before {
color: #FDE16D;
content: '\2605'; /* Full star in UTF8 */
position: absolute;
left: 0;
width: 50%;
overflow: hidden;
text-shadow: 0 0 2px rgba(0, 0, 0, 0.7);
}
.logo {
background-position: left 16px center;
background-repeat: no-repeat;
background-image: url(https://www.bigoven.com/assets/images/icons/bigoven-recipes.png);
background-color: #fefefe;
height: 38px;
text-align: left;
padding: 16px;
padding-left: 72px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, .14), 0 3px 1px -2px rgba(0, 0, 0, .2), 0 1px 5px 0 rgba(0, 0, 0, .12);
}
.logo > a {
text-decoration: none;
}
.heading {
text-align: center;
padding-bottom: 8px;
}
.heading > #summary {
font-weight: 500;
}
.heading > small {
color: #656565;
}
.lower-wrapper {
margin: 0em 1em 0em 1em;
}
.title-description {
max-width: 310px;
margin: 0 auto;
}
</style>
</head>
<body>
<div>
...
</div>
</body>
</html>
I'm having a problem with writing correct 'IF' statement in .NET and AMP. Statment look like this and it placed in a head section where suppose to be. AMP Validator throws me three errors:
Tag outside the body section
and two of 'link rel=cannonical' is 'body', but it can only be 'head'
Here is a code snippet of my if statement from my cshtml template:
#if (!Model.IsBookmark)
{
<link rel="canonical" href="#(Model.CanonicalUrl())"/>
}
else
{
<link rel="canonical" href="#Model.BookmarkURL"/>
What is the correct way to handle if statement in AMP?

Issue While fetching bodyHTML using partID in Mailcore2

I tried fetching the bodyHTML using the following code
MCOIMAPFetchContentOperation * op = [imapsession fetchMessageAttachmentOperationWithFolder:folderName uid:uid partID:partId encoding:MCOEncoding8Bit
And I got the bodyHTML with some unwanted extra code. The Html I got for one of the mail is
<div style="padding-bottom: 20px;"></div><div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org=
<br/>/TR/xhtml1/DTD/xhtml1-strict.dtd">
<br/><html xmlns=3D"http://www.w3.org/1999/xhtml">
<br/><head>
<br/><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8" />
<br/><meta name=3D"viewport" content=3D"width=3Ddevice-width" />
<br/><meta http-equiv=3D"X-UA-Compatible" content=3D"IE=3Dedge" />
<br/></head>
<br/><body style=3D"-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; =
<br/>background: #EEEEEE; color: #222222; font-family: 'Open Sans', Arial, sans-=
<br/>serif; font-size: 14px; font-weight: normal; line-height: 22px; margin: 0; =
<br/>min-width: 100%; padding: 0; text-align: left; width: 100% !important" bgco=
<br/>lor=3D"#EEEEEE"><style type=3D"text/css">
<br/>body {
<br/>width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; -m=
<br/>s-text-size-adjust: 100%; margin: 0; padding: 0;
<br/>}
<br/>.ExternalClass {
<br/>width: 100%;
<br/>}
<br/>.ExternalClass {
<br/>line-height: 100%;
<br/>}
<br/>#backgroundTable {
<br/>margin: 0; padding: 0; width: 100% !important; line-height: 100% !important=
<br/>;
<br/>}
<br/>img {
<br/>outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; widt=
<br/>h: auto; max-width: 100%; float: left; clear: both; display: block;
<br/>}
<br/>body {
<br/>color: #222222; font-family: "Open Sans", Arial, sans-serif; font-weight: n=
<br/>ormal; padding: 0; margin: 0; text-align: left; line-height: 1.3;
<br/>}
<br/>body {
<br/>font-size: 14px; line-height: 22px;
<br/>}
<br/>a:hover {
<br/>color: #222222 !important;
<br/>}
And I am not able to render it on the web view. But when I tried fetching the body using the following method
MCOIMAPFetchContentOperation * opr = [imapsession fetchMessageOperationWithFolder:folderName uid:uid urgent:YES];
I got the proper body html and was able to render it on the webview .The html I got for the above method is:-
<div style="padding-bottom: 20px;"></div><div><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content=
"text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
</head>
<body style=
"-ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; background: #EEEEEE; color: #222222; font-family: 'Open Sans', Arial, sans-serif; font-size: 14px; font-weight: normal; line-height: 22px; margin: 0; min-width: 100%; padding: 0; text-align: left; width: 100% !important"
bgcolor="#EEEEEE">
<style type="text/css">
/*<![CDATA[*/
body {
width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; margin: 0; padding: 0;
}
.ExternalClass {
width: 100%;
}
.ExternalClass {
line-height: 100%;
}
#backgroundTable {
margin: 0; padding: 0; width: 100% !important; line-height: 100% !important;
}
img {
outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: auto; max-width: 100%; float: left; clear: both; display: block;
}
body {
color: #222222; font-family: "Open Sans", Arial, sans-serif; font-weight: normal; padding: 0; margin: 0; text-align: left; line-height: 1.3;
}
body {
font-size: 14px; line-height: 22px;
}
a:hover {
color: #222222 !important;
}
Is there any parser or any other way to get the body html .Since I have to use the method using partID to fetch the bodyHTML.
The issue was while fetching the message using part it always uses the MCOEncoding8Bit for encoding instead of that we have to give the encoding which we get while fetching the message as shown below.
for(MCOAbstractPart *abstractPart in multiAbstractPart.parts)
{
MCOIMAPPart *part = (MCOIMAPPart *)abstractPart;
MCOIMAPFetchContentOperation * op = [imapsession fetchMessageAttachmentOperationWithFolder:folderName uid:uid partID:partId encoding:part.encoding];
}

Resources