How to save the SVG element to a static file with Dart? - dom

I have to work with SVG elements using some DOM operation in Dart. After adding and changing some elements under the "svg" tag, I want to export the final SVG elements to a static file. Is there any API can do it?
Thanks!

You can use the download attribute on <a> elements. This tells the browser to download the resource instead of navigating to it.
You can get the contents of the SVG with innerHtml.
Here is an example.
First, the HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Svgtest</title>
<link rel="stylesheet" href="svgtest.css">
</head>
<body>
<h1>Svgtest</h1>
<div id="container">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>
</svg>
</div>
<script type="application/dart" src="svgtest.dart"></script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
Next, the Dart code:
import 'dart:html';
void main() {
Element container = query('#container');
String contents = container.innerHtml;
Blob blob = new Blob([contents]);
AnchorElement downloadLink = new AnchorElement(href: Url.createObjectUrlFromBlob(blob));
downloadLink.text = 'Download me';
downloadLink.download = 'svg_contents.svg';
Element body = query('body');
body.append(downloadLink);
}
Here is the browser coverage: http://caniuse.com/#feat=download At the time of this writing, Firefox, Chrome, and Opera support the download attribute.
(Note: there is no way to directly save a file to the native OS filesystem with HTML5.)

For IE 10+:
import 'dart:html';
import 'dart:js';
import "package:js/js.dart";
#JS("navigator.msSaveBlob")
external void msSaveBlob(blob, filename);
void main() {
Element container = query('#container');
String contents = container.innerHtml;
Blob blob = new Blob([contents]);
if (js.context['navigator']['msSaveBlob'] != null) {
msSaveBlob(blob, 'svg_contents.svg');
} else {
AnchorElement downloadLink = new AnchorElement(href: Url.createObjectUrlFromBlob(blob));
downloadLink.text = 'Download me';
downloadLink.download = 'svg_contents.svg';
Element body = query('body');
body.append(downloadLink);
}
}

Related

Get title from html page - FLUTTER

I would like to create a preview of a url with the title and thumbnail in flutter
I downloaded the web page correctly with the http package, but I can't get the tag
https://flutter.dev/docs/cookbook/networking/fetch-data
var document = parse('''<!doctype html>
<html lang="en">
<head>
<title>Hello World!</title>
</head>
<body>
<h1>HELLO WORLD!</h1>
<p>PAGE HTML!</p>
<img src="image.jpg">
</body>
</html>''');
print("PRINT - "+document.body.getElementsByTagName('h1').toString()); --> ("PRINT - [<html h1>]") *
*I would like to get the h1 title : HELLO WORLD!
Thank you.
You can use flutter-link-preview plugin:
import 'package:flutter/material.dart';
import 'package:link_preview/widget/whatsapp/index.dart';
WhatsAppLinkPreview whatsapp = WhatsAppLinkPreview();
void main() {
runApp(MaterialApp(
home: Scaffold(
body: Center(
child: whatsapp.build('https://whatsapp.com')
),
),
));
}
i did it once using
html plugin
it gives you something like
var document = parse(response.body);
document.getElementById // or tagName or className
but you will get weird html element needs to be parsed
print(document.body.getElementsByTagName('h1')[0].innerHtml);
works most of the time.

I was trying out Uber's deck.gl by adding the component to my react app. But nothing appears. Any help would be appreciated

I was trying out Uber's deck.gl by adding the component to my react app. But nothing appears.
I believe it could be related to mapbox. It appeared once but that was it.
I set the width, height, etc. But nothing works.
This is basic example in their site.
Deck Gl with React
Here is my code. deckgl.component.js
import React, { Component } from 'react';
import { render } from 'react-dom';
import { StaticMap } from 'react-map-gl';
import DeckGL, { LineLayer, ScatterplotLayer } from 'deck.gl';
const MAPBOX_ACCESS_TOKEN = '<MAPBOX_TOKEN>';
// Viewport settings
const INITIAL_VIEW_STATE = {
latitude: 37.785164,
longitude: -122.41669,
zoom: 16,
bearing: -20,
pitch: 60
};
class DeckGlComponent extends Component {
render() {
return (
<DeckGL initialViewState={INITIAL_VIEW_STATE} controller={true} width="100%" height="100%">
<StaticMap mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN} />
<LineLayer
data={[{ sourcePosition: [-122.41669, 37.7883], targetPosition: [-122.41669, 37.781] }]}
getStrokeWidth={5}
/>
<ScatterplotLayer
data={[{ position: [-122.41669, 37.79] }]}
radiusScale={100}
getFillColor={[0, 0, 255]}
/>
</DeckGL>
);
}
}
export default DeckGlComponent;
and index.js
import React from 'react';
import { render } from 'react-dom';
import './index.css';
import * as serviceWorker from './serviceWorker';
import DeckGlComponent from './deckgl.component';
render(
<DeckGlComponent />,
document.getElementById('root')
);
serviceWorker.unregister();
It's absolutely basic. But nothing turns up. I created a new mapbox token just to be sure and still nothing.
According to your description (since there's not too much information), and mapbox token is active as you said, I suspect if you create a HTML file contains root element, like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#root {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
</html>
This file is required when you calling these codes:
render(
<DeckGlComponent />,
document.getElementById('root')
);
You can put your code on codepen or some online editors, so that we can help you more specifically.
Besides, I recommend you read codes in this folder https://github.com/uber/deck.gl/tree/master/examples/get-started rather than the codes in documents. Sometimes, codes in documents is for explaining concepts, and not ready for running.

Unable to Execute Jquery from sidebar in Addon Firefox SDK

I am new to this Firefox SDK , but what i have understood you can execute content Scripts on Pages.
Here is the Code
MAIN.JS
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: data.url("index.html"),
onReady: function (worker) {
worker.port.emit('turl',tabs.activeTab.url);
}
});
SIDEBAR.JS
$('#bt1').on('click',function(){
$('title').textContent;
});
INDEX.HTML
<!DOCTYPE HTML>
<html>
<body>
<input type="button" id="bt1" value="Click Me"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="sidebar.js"></script>
</body>
</html>
But this code tries to find out title of the Sidebar html.
I have also tried using contentScriptFile in Main.js but same thing happened
var tabs = require("sdk/tabs");
var data = require("sdk/self").data;
var sidebar = require("sdk/ui/sidebar").Sidebar({
id: 'my-sidebar',
title: 'My sidebar',
url: data.url("index.html"),
contentScriptFile: [data.url("jquery.min.js"),data.url("sidebar.js")],
onReady: function (worker) {
worker.port.emit('turl',tabs.activeTab.url);
}
});
The Jquery code is in the sidebar.js
Still no Results.Please help
There is no contentScriptFile for the Sidebar class.
Try this: copy the jquery library to a local file in the data folder, then refer to it using a relative path. Sidebars can only use 'local' JS, they cannot load scripts from the internet.

cross rider extension to fetch new posts from feed using google feeds api

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]

Show local HTML file with JavaScript in SWT Browser widget in RAP

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.