I've tried creating pages using the 'standard layout' and 'custom layout' but neither allows the use of the {block:Posts} variable(s). I need to re-create essentially the archive page but with some custom css. Is there any way to accomplish this?
If I try $("#someDiv").load("/archive", "#content"); the whole page formatting gets screwed up. Is there a way to load just the <a> tags into a div on my custom page?
Or would it be possible to use the API entirely client side to accomplish this?
Any ideas on this would be appreciated.
I came up with two possible solutions if anyone else finds themselves stuck on this. I abandoned this first one before finalizing it, so it's a bit rough but a good start. It uses the API to load photos (that was all I needed) as you scroll down the page.
<script>
function getPhotos(offset){
$.ajax({
url: "http://api.tumblr.com/v2/blog/[tumblr].tumblr.com/posts?api_key=[key]&offset="+offset,
dataType: 'jsonp',
success: function(results){
loaded += 20;
total = results.response.blog.posts;
if(total > loaded){
results.response.posts.forEach(function(post){
post.photos.forEach(function(photo){
$("#photos ul").append("<li class='"+post.tags.join(" ")+"'><img src='"+photo.alt_sizes[0].url+"'></li>");
$("#photos").imagesLoaded(function(){
$("#photos").masonry({
itemSelector: 'li'
});
});
});
});
if($("#photos ul").height() < $(window).height()){
getPhotos(loaded);
}
}
}
});
}
loaded = 0;
getPhotos(loaded);
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100) {
getPhotos(loaded);
}
});
</script>
What I've ended up doing is just using an iframe with a custom stylesheet appended to the head.
html:
<head>
<script src="http://[remote location]/frame.js"></script>
</head>
<body>
<div id="photos">
<iframe name="frame1" id="frame1" src="http://[tumblr]/archive" frameBorder="0"></iframe>
</div>
</body>
frame.js:
$(function(){
function insertCSS(){
var frm = frames['frame1'].document;
var otherhead = frm.getElementsByTagName("head")[0];
if(otherhead.length != 0){
var link = frm.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("href", "http://[remote location]/frame.css");
otherhead.appendChild(link);
setTimeout(function(){$("#frame1").show();}, 200);
clearInterval(cssInsertion);
}
}
cssInsertion = setInterval(insertCSS, 500);
//setTimeout(insertCSS, 1000);
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() > $(document).height() - 100 && $("#frame1").height() < 50000) {
$("#frame1").css("height", "+=1000px");
}
});
});
frame.css (stylesheet appended into iframe)
body{
overflow: hidden;
}
#nav_archive{
display: none;
}
.heading{
display: block !important;
}
.old_archive #content{
margin: 0 auto 0;
}
style.css (stylesheet on page where iframe is located)
#frame1{
border: none;
width: 100%;
height: 3000px;
overflow: hidden;
display: none;
}
Related
I want the users of my app to be able to select text (words, but also whole sentences) in a WebViewWidget, and have an audio of that text played to them (via tts). I only want this to work with u̲n̲d̲e̲r̲l̲i̲n̲e̲d̲ text (or text visually highlighted and set apart from the rest in any other way).
This is part of my Widget tree, where I have tested a few gestureRecognizers (please read the comments):
child: GestureDetector(
//gestureRecognizers of WebViewWidget don't do anything without this GestureDetector,
//see: https://stackoverflow.com/questions/58811375/tapgesturerecognizer-not-working-in-flutter-webview#answer-59298134
onTap: () => print('this line doesnt get printed'),
child: WebViewWidget(
controller: _controller,
gestureRecognizers: {
Factory<LongPressGestureRecognizer>(() => LongPressGestureRecognizer()
..onLongPress = () {
print('onLongPress');
}
..onLongPressStart = (LongPressStartDetails details) {
print('onLongPressStart, ${details.globalPosition}, ${details.localPosition}');
}),
Factory<TapGestureRecognizer>(() => TapGestureRecognizer()
..onTap = () {
print('onTap'); //this doesn't get printed at all
}
..onTapDown = (TapDownDetails details) {
//comment: this doesn't get printed unless I tap for a little long time (not as long as longPress)
print('onTapDown, details: $details');
/*TODO: I want to get a text selection and play audio (with tts)
String selectedText = ...?
TTSHelper.speak(text: selectedText);
*/
}),
},
),
),
Another approach to a possible solution for what I want
I have an initialization function, where I take html (without the html, body & head tags...) from firestore and wrap it in the html, body & head tags along with some custom CSS.
If there is no way to achieve my goal with Dart code, maybe there is a way for me to add JavaScript to the html, so that underlined words/sentences can be tapped to play audio via tts, or at least send that text over to my Dart code somehow?
String _prepareHTML(String content) {
return """<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {background-color: ${getCSSColor(context, CustomColors.mainAppBG)};}
h1, h2, h3, h4, h5, h6 {color: ${getCSSColor(context, CustomColors.blueWhiteText)};}
p {color: ${getCSSColor(context, CustomColors.text)};}
table {
width: 100%;
table-layout: fixed;
word-wrap: break-word;
}
table, tr, th, td {
color: ${getCSSColor(context, CustomColors.text)};
border: 1px solid ${getCSSColor(context, CustomColors.text)};
border-collapse: collapse;
}
th, td {
padding: 6px 12px;
font-weight: bold;
font-size: 1.25em;
}
</style>
</head>
<body>
$content
</body>
</html>""";
}
I think you might be able to achieve what you want by using some javascript and a javascriptChannel on the WebViewWidget. General idea below:
var controller = WebViewController();
controller.addJavascriptChannel(
JavascriptChannel(
name: 'underlinedTextSelectChannel',
onMessageReceived: (message) {
var data = json.decode(message.message);
var text = data.text as String;
TTSHelper.speak(text: selectedText);
}
)
)
...
var html = """
<html>
...
<body>
$content
# Within content:
This is some text <p class="underlined-text">Say this!</p> Don't say this.
<script>
var underlinedTexts = document.querySelectorAll('.underlined-text');
for(var t of underlinedTexts) {
t.addEventListener('onClick', (e) => {
underlinedTextSelectChannel.postMessage(JSON.stringify({
text: e.target.innerText
}))
})
}
</script>
</body>
</html>
"""
I am trying to learn how to use the interact.js library and I cant get the resizing example to be draggable. I can resize the div ".resize-drag" but I don´t know how to get it draggable. Can anyone tell me is wrong with my code?
This code is only so that I can learn to implement the resize example provided at http://interactjs.io/ So far I´ve tried using npm instead of the script tag. When I copied the example below from the top of the interact.js website and renamed the element ".item" in the interact claus but that did not work
interact('.item').draggable({
onmove(event) {
console.log(event.pageX,
event.pageY)
}
})
I suspected it might be a syntax error so I also tried adding semicolon behind the function but that didn´t seem to be the problem. Please have a look at my entire code below to see what I have done wrong.
<!DOCTYPE html>
<!--
To change this license header, choose License Headers in Project
Properties.
To change this template file, choose Tools | Templates
and open the template in the editor.
-->
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
.resize-drag {
background-color: #29e;
color: white;
font-size: 20px;
font-family: sans-serif;
border-radius: 8px;
padding: 20px;
margin: 30px 20px;
width: 120px;
/* This makes things *much* easier */
box-sizing: border-box;
}
.resize-container {
display: inline-block;
width: 100%;
height: 240px;
background-color: lightblue;
}
</style>
<script
src="https://unpkg.com/interactjs#1.3.4/dist/interact.min.js"></script>
<script type="text/javascript">
interact('.resize-drag').draggable({
onmove(event) {
console.log(event.pageX,
event.pageY)
}
})
interact('.resize-drag')
.draggable({
onmove: window.dragMoveListener,
restrict: {
restriction: 'parent',
elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
},
})
.resizable({
// resize from all edges and corners
edges: { left: true, right: true, bottom: true, top: true },
// keep the edges inside the parent
restrictEdges: {
outer: 'parent',
endOnly: true,
},
// minimum size
restrictSize: {
min: { width: 100, height: 50 },
},
inertia: true,
})
.on('resizemove', function (event) {
var target = event.target,
x = (parseFloat(target.getAttribute('data-x')) || 0),
y = (parseFloat(target.getAttribute('data-y')) || 0);
// update the element's style
target.style.width = event.rect.width + 'px';
target.style.height = event.rect.height + 'px';
// translate when resizing from top or left edges
x += event.deltaRect.left;
y += event.deltaRect.top;
target.style.webkitTransform = target.style.transform =
'translate(' + x + 'px,' + y + 'px)';
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
target.textContent = Math.round(event.rect.width) + '\u00D7' +
Math.round(event.rect.height);
});
</script>
</head>
<body>
<div class="resize-container">
<div class="resize-drag">
Resize from any edge or corner
</div>
</div>
</body>
</html>
I want to be able to drag the div and not just resize it.
I recently struggled with that as well, and it turned out that the 'resizing' code blurbs don't have all the code. The js is missing window.dragMoveListener and dragMoveListener, which is found in the 'dragging' section.
Specifically you need to add this
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform =
target.style.transform =
'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
}
// this is used later in the resizing and gesture demos
window.dragMoveListener = dragMoveListener;
I am trying to create an extension to display all the latest posts fetched from my feed using google feeds api. To implement this, I have added this code in background.js:
appAPI.ready(function() {
// Global variable to hold the toggle state of the button
var buttonState = true;
// Sets the initial browser icon
appAPI.browserAction.setResourceIcon('images/icon.png');
// Sets the tooltip for the button
appAPI.browserAction.setTitle('My Postreader Extension');
appAPI.browserAction.setPopup({
resourcePath:'html/popup.html',
height: 300,
width: 300
});});
and in popup.html,
<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript">
function crossriderMain($) {eval(appAPI.resources.get('script.js')); }</script>
</head>
<body><div id="feed"></div></body></html>
The script.js file is-
google.load("feeds", "1");
function initialize() {
var feed = new google.feeds.Feed("http://www.xxxxx.com/feed/");
feed.setNumEntries(10);
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("feed");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
var link = document.createElement('a');
link.setAttribute('href', entry.link);
link.setAttribute('name', 'myanchor');
div.appendChild(document.createTextNode(entry.title));
div.appendChild(document.createElement('br'));
div.appendChild(link);
div.appendChild(document.createElement('br'));
container.appendChild(div);
}
}
});
}
google.setOnLoadCallback(initialize);
But I am unable to get desired result.The popup doesn't display anything.It just remain blank.
Since you are using a resource file for the popup's content, it's best to load the remote script from the crossriderMain function, as follows:
<!DOCTYPE html>
<html>
<head>
<!-- This meta tag is relevant only for IE -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript">
function crossriderMain($) {
appAPI.db.async.get('style-css', function(rules) {
$('<style type="text/css">').text(rules).appendTo('head');
});
appAPI.request.get({
url: 'http://www.google.com/jsapi',
onSuccess: function(code) {
$.globalEval(code);
appAPI.db.async.get('script-js', function(code) {
// runs in the context of the extension
$.globalEval(code.replace('CONTEXT','EXTN'));
// Alternatively, run in context of page DOM
$('<script type="text/javascript">').html(code.replace('CONTEXT','PAGE DOM')).appendTo('head');
});
}
});
}
</script>
</head>
<body>
<h1>Hello World</h1>
<div id="feed"></div>
</body>
</html>
[Disclaimer: I am a Crossrider employee]
For my RAP-project I need to show some charts. Because I haven't found any widget for this purpose, my plan was to use the browser widget, so I can use JavaScript-Plugins like Highcharts or Chartsjs. But I can't get it working. If I set an HTML-File in browser.setUrl, the browser widget don't show anything, not even simple HTML. The JavaScript-Console in Chrome says
Not allowed to load local resource
If I enter the HTML-Code with the setText method it shows the HTML, but JavaScript is not working, it don't load external JS-File like the jQuery-library.
Can't this be done this way? Or where is my failure? (Sorry for my bad englisch, I'm not native speaker.)
Here's the Java-Code I tried:
browser = new Browser(composite, SWT.NONE);
browser.setTouchEnabled(true);
browser.setBounds(10, 10, 358, 200);
browser.setUrl("D:\\STATS\\statistiken.html");
Or this:
File file = new File("D:\\STATS\\statistiken.html");
browser = new Browser(composite, SWT.NONE);
browser.setTouchEnabled(true);
browser.setBounds(10, 10, 358, 200);
browser.setUrl(file.toURI().toString());
I tried also some other things, there were not working to.
With HTML in setText-method (I tried external libraries and local libraries in same folder):
browser = new Browser(composite, SWT.NONE);
browser.setBounds(10, 10, 358, 200);
browser.setText(
"<html>" +
"<head>" +
"<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js\"></script>" +
"<script src=\"http://code.highcharts.com/highcharts.js\"></script>" +
"<script src=\"http://code.highcharts.com/modules/exporting.js\"></script>" +
"</head>" +
"<body>" +
"<p>Test</p>" +
"<div id=\"container\" style=\"min-width: 400px; height: 400px; margin: 0 auto\"></div>" +
"</body>" +
"</htm>");
Hope someone can help me with this problem.
Local links will not be resolved and external links will not be loaded(Cross Domain problem) in your case.
I could suggest you 2 Solutions.
Solution 1:
This is useful when you have very few resources(html, javascript, css) to render on Browser and no Hyperlinks(which when cliked will load a different page).
You can use Velocity. Read this to start using Velocity.
You can have all the static content in Velocity Template and inject Dynamic content into it at Runtime.
Here is the excerpt from one of my Projects.
init.vm
<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
.transcript {
background-color: #d2d2d2;
}
.messageBlock {
margin-left: 4px;
margin-bottom: -15px;
}
.message {
margin-left: 115px;
word-wrap: break-word;
white-space: -moz-pre-wrap;
_white-space: pre;
white-space: pre-wrap;
}
</style>
</head>
<script type="text/javascript">
function resizeChatWindow() { var divT = document.getElementById("divTranscript"); divT.style.height = (document.body.clientHeight - getTopAreaHeight()) + "px"; divT.style.width = (document.body.clientWidth) + "px"; divT.style.overflow = "auto"; divT.style.position = "absolute"; divT.style.left = "0px"; divT.style.top = getTopAreaHeight() + "px";}
function getTopAreaHeight() { var chatAlert = document.getElementById("chatAlert"); if (chatAlert) { return chatAlert.clientHeight; } return document.getElementById("divBody").clientHeight;}
isChat=false; window.onresize=resizeChatWindow;
</script>
<script type="text/javascript">
$scriptText
</script>
<script type="text/javascript">
function addChat(chatText){
$("#divTranscript").append(chatText);
$("#divTranscript").animate({ scrollTop: $("#divTranscript")[0].scrollHeight }, "slow");
}
</script>
<body onload="resizeChatWindow();">
<div id="divBody"></div>
<div id="divTranscript">$history</div>
</body>
</html>
VelocityUtils
private void init() throws Exception {
ve = new VelocityEngine();
Properties velocityProperties = new Properties();
velocityProperties.put("resource.loader", "class");
velocityProperties.put("class.resource.loader.description", "Velocity Classpath Resource Loader");
velocityProperties.put("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
ve.init(velocityProperties);
//ve.init();
}
public String getInitHtml(String history) throws ResourceNotFoundException, ParseErrorException, Exception {
/* now render the template into a StringWriter */
StringWriter writer = null;
/* next, get the Template */
Template t = ve.getTemplate("templates/init.vm","UTF-8");
/* create a context and add data */
VelocityContext context = new VelocityContext();
String script = IOUtils.toString(VelocityUtils.class.getResourceAsStream("script/jquery.min.js"), "UTF-8");
context.put("scriptText", script); //You can even have all the script content in init.vm rather than injecting it at runtime.
context.put("history", StringUtils.defaultIfBlank(history, StringPool.BLANK));
writer = new StringWriter();
t.merge(context, writer);
/* show the World */
String returnMe = writer.toString();
return returnMe;
}
set the returned String in Browser.setText()
Solution 2:
I explained it here.
How Display Tinybox 2 Popup box on page load?
Use this code on page on which you want to Display Tinybox 2 Popup box on page load
<script type="text/javascript">
window.onload = function()
{
TINY.box.show(html:'You content go here', 1, 400, 350, 1)
}
</script>
To close Popup box after specific time use this
<script type="text/javascript">
window.onload = function()
{
TINY.box.show('contentfile.html', autohide:20, 1, 400, 350, 1)
}
</script>
This will close popup after 20 seconds.
i did it this way.
window.onload = function()
{
TINY.box.show({
url: '/message.html',
width: 403, height: 200, opacity: 20
});
}