Browse Source

Merge branch 'develop'

develop
Matt Baer 7 years ago
parent
commit
b037bc04ae
11 changed files with 255 additions and 43 deletions
  1. +18
    -0
      H.js
  2. +4
    -4
      README.md
  3. +24
    -13
      context.js
  4. +18
    -0
      fonts.css
  5. BIN
      fonts/lora-700.woff2
  6. BIN
      fonts/lora.woff2
  7. BIN
      fonts/open-sans.woff2
  8. +4
    -0
      img/ic_launch.svg
  9. +5
    -5
      manifest.json
  10. +52
    -8
      popup.html
  11. +130
    -13
      popup.js

+ 18
- 0
H.js View File

@@ -78,4 +78,22 @@ var H = {
return post;
},
getTitleStrict: function(content) {
var eol = content.indexOf("\n");
var title = "";
var newContent = content;
if (content.indexOf("# ") === 0) {
// Title is in the format:
// # Some title
if (eol !== -1) {
// First line should start with # and end with \n
newContent = content.substring(eol).leftTrim();
title = content.substring("# ".length, eol);
}
}
return {
title: title,
content: newContent
};
},
};

+ 4
- 4
README.md View File

@@ -1,9 +1,9 @@
Paste Chrome extension
======================
Write.as Chrome extension
=========================

Paste lets you instantly share text or code from your browser.
Write.as for Chrome lets you instantly share text from your browser.

![Selecting text in Paste](https://paste.as/images/pic01.jpg)
![Selecting text in Write.as](https://paste.as/images/pic01.jpg)

# License



+ 24
- 13
context.js View File

@@ -1,9 +1,14 @@
function publish(content, font) {
if (content.trim() == "") {
return;
}

var post = H.getTitleStrict(content);
var http = new XMLHttpRequest();
var url = "https://write.as/api/";
var url = "https://write.as/api/posts";
var lang = navigator.languages ? navigator.languages[0] : (navigator.language || navigator.userLanguage);
lang = lang.substring(0, 2);
var params = "w=" + encodeURIComponent(content) + "&font=" + font + "&lang=" + lang;
var params = "body=" + encodeURIComponent(post.content) + "&title=" + encodeURIComponent(post.title) + "&font=" + font + "&lang=" + lang + "&rtl=auto";
http.open("POST", url, true);

//Send the proper header information along with the request
@@ -11,18 +16,24 @@ function publish(content, font) {

http.onreadystatechange = function() {
if (http.readyState == 4) {
if (http.status == 200) {
data = http.responseText.split("\n");
if (http.status == 201) {
data = JSON.parse(http.responseText);
// Pull out data parts
url = data[0];
id = url.substr(url.lastIndexOf("/")+1);
editToken = data[1];
// Save the data
posts = JSON.parse(H.get('posts', '[]'));
posts.push(H.createPost(id, editToken, content));
H.set('posts', JSON.stringify(posts));
id = data.data.id;
if (font == 'code' || font === 'mono') {
url = "https://paste.as/"+id;
} else {
url = "https://write.as/"+id;
}
editToken = data.data.token;

// Save the data if user wasn't logged in
if (typeof data.data.owner === 'undefined' || data.data.owner == "") {
posts = JSON.parse(H.get('posts', '[]'));
posts.push(H.createPost(id, editToken, post.content));
H.set('posts', JSON.stringify(posts));
}

// Launch post
chrome.tabs.create({ url: url });
} else {


+ 18
- 0
fonts.css View File

@@ -0,0 +1,18 @@
@font-face {
font-family: 'Lora';
font-style: normal;
font-weight: 400;
src: local('Lora'), local('Lora-Regular'), url('fonts/lora.woff2') format('woff2');
}
@font-face {
font-family: 'Lora';
font-style: normal;
font-weight: 700;
src: local('Lora Bold'), local('Lora-Bold'), url('fonts/lora-700.woff2') format('woff2');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
src: local('Open Sans'), local('OpenSans'), url('fonts/open-sans.woff2') format('woff2');
}

BIN
fonts/lora-700.woff2 View File


BIN
fonts/lora.woff2 View File


BIN
fonts/open-sans.woff2 View File


+ 4
- 0
img/ic_launch.svg View File

@@ -0,0 +1,4 @@
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none"/>
<path d="M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z"/>
</svg>

+ 5
- 5
manifest.json View File

@@ -1,9 +1,10 @@
{
"manifest_version": 2,

"name": "Paste by Write.as",
"description": "Effortlessly share text online.",
"version": "1.3",
"name": "Write.as for Chrome",
"short_name": "Write.as",
"description": "Publish a thought in seconds.",
"version": "2.0",

"icons": {
"16": "icon16.png",
@@ -28,8 +29,7 @@
"activeTab",
"contextMenus",
"webRequest",
"*://*.write.as/",
"https://fonts.googleapis.com/"
"*://*.write.as/"
],
"externally_connectable": {
"matches": ["*://*.write.as/*"]


+ 52
- 8
popup.html View File

@@ -1,7 +1,7 @@
<!doctype html>
<html>
<head>
<title>Paste by Write.as</title>
<title>Write.as</title>
<style>
body, input[type=submit], label[for=norm], textarea.norm {
font-family: Lora, serif;
@@ -38,8 +38,15 @@
color: white;
text-align: right;
margin-left: 0.5em;
width: 7em;
text-align: center;
transition: all .2s ease-out;
border-radius: .25em;
}
input[type=submit].disabled {
input[type=submit]:hover {
background-color: #7d82c4;
}
input[type=submit].disabled, input[type=submit].disabled:hover {
background: #ddd;
color: #999;
border-color: #eee;
@@ -47,23 +54,38 @@
#publish-holder, #result-holder {
text-align: right;
}
#result-holder {
#result-holder, #account-tools {
display: none;
}
#url {
width: 18em;
margin-right: 0.5em;
}
label[for=mono], label[for=code], textarea.mono, textarea.code {
label[for=mono], label[for=wrap], label[for=code], textarea.mono, textarea.wrap, textarea.code {
font-family: monospace, monospace;
font-size: 1em;
}
textarea.mono, textarea.code {
white-space: pre;
}
label, label[for=mono], label[for=wrap], label[for=code] {
font-size: 0.86em;
}
body.popout #publish-holder, body.popout #result-holder {
position: fixed;
bottom: 1em;
left: 1em;
right: 1em;
}
#account-tools {
margin-top: -0.5em;
margin-bottom: 0.5em;
font-size: 0.86em;
}
#account-tools a {
line-height: 24px;
margin-left: 0.5em;
}
body.popout textarea {
position: fixed;
top: 0;
@@ -72,10 +94,29 @@
bottom: 4em;
border: 0;
border-bottom: 1px solid #dfdfdf;
min-height: 0;
}
a#popout {
padding: 0.5em;
position: absolute;
left: 0.75em;
bottom: 0.75em;
}
a#popout img {
vertical-align: middle;
}
body.popout a#popout {
display: none;
}
#username {
font-weight: bold;
}
#sync.disabled {
display: inline;
color: #999;
font-style: italic;
text-decoration: none;
}
</style>

<script src="H.js"></script>
@@ -83,23 +124,26 @@
</head>
<body>
<form name="postForm" method="post">
<textarea id="content" placeholder="Paste..."></textarea>
<div id="account-tools">
Writing as <span id="username">write.as</span>. <a id="sync" href="#">Sync...</a>
</div>
<textarea id="content" placeholder="Write..."></textarea>
<div id="result-holder">
<input id="url" type="url" readonly />
<a id="url-link" target="_blank">Open</a>
</div>
<div id="publish-holder">
<a href="#" id="popout">Pop out</a>
<input type="radio" name="font" value="sans" id="sans" checked="checked" /><label for="sans"> Sans</label>
<input type="radio" name="font" value="norm" id="norm" /><label for="norm"> Serif</label>
<input type="radio" name="font" value="mono" id="mono" /><label for="mono"> Monospace</label>
<input type="radio" name="font" value="wrap" id="wrap" /><label for="wrap"> Wrap</label>
<input type="radio" name="font" value="code" id="code" /><label for="code"> Code</label>
<input id="publish" type="submit" value="Publish" />
<a href="#" id="popout"><img src="img/ic_launch.svg" /></a>
</div>
</form>
<link href='https://fonts.googleapis.com/css?family=Lora:400,700' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,700' rel='stylesheet' type='text/css'>
<link href='fonts.css' rel='stylesheet' type='text/css'>
</body>
</html>


+ 130
- 13
popup.js View File

@@ -8,14 +8,15 @@ function publish(content, font) {
}
$publish.classList.add('disabled');
$publish.value = "Publishing...";
setPublishText(font, true);
$publish.disabled = true;
var post = H.getTitleStrict(content);
var http = new XMLHttpRequest();
var url = "https://write.as/api/";
var url = "https://write.as/api/posts";
var lang = navigator.languages ? navigator.languages[0] : (navigator.language || navigator.userLanguage);
lang = lang.substring(0, 2);
var params = "w=" + encodeURIComponent(content) + "&font=" + font + "&lang=" + lang;
var params = "body=" + encodeURIComponent(post.content) + "&title=" + encodeURIComponent(post.title) + "&font=" + font + "&lang=" + lang + "&rtl=auto";
http.open("POST", url, true);

//Send the proper header information along with the request
@@ -24,18 +25,23 @@ function publish(content, font) {
http.onreadystatechange = function() {
if (http.readyState == 4) {
$publish.classList.remove('disabled');
$publish.value = "Publish";
setPublishText(font, false);
$publish.disabled = false;
if (http.status == 200) {
if (http.status == 201) {
$publish.style.display = 'none';

data = http.responseText.split("\n");
data = JSON.parse(http.responseText);
// Pull out data parts
url = data[0];
id = url.substr(url.lastIndexOf("/")+1);
editToken = data[1];
id = data.data.id;
if (font == 'code' || font === 'mono') {
url = "https://paste.as/"+id;
} else {
url = "https://write.as/"+id;
}
editToken = data.data.token;

document.getElementById("account-tools").style.display = 'none';
document.getElementById("publish-holder").style.display = 'none';
document.getElementById("result-holder").style.display = 'inline';
@@ -44,10 +50,12 @@ function publish(content, font) {
var $urlLink = document.getElementById("url-link");
$urlLink.href = url;

// Save the data
posts = JSON.parse(H.get('posts', '[]'));
posts.push(H.createPost(id, editToken, content));
H.set('posts', JSON.stringify(posts));
// Save the data if user wasn't logged in
if (typeof data.data.owner === 'undefined' || data.data.owner == "") {
posts = JSON.parse(H.get('posts', '[]'));
posts.push(H.createPost(id, editToken, post.content));
H.set('posts', JSON.stringify(posts));
}
} else {
alert("Failed to post. Please try again.");
}
@@ -56,6 +64,14 @@ function publish(content, font) {
http.send(params);
}

function setPublishText(font, isPublishing) {
if (font === 'code' || font === 'mono') {
$publish.value = isPublishing ? 'Pasting...' : 'Paste';
} else {
$publish.value = isPublishing ? 'Publishing...' : 'Publish';
}
}

document.addEventListener('DOMContentLoaded', function() {
$content = document.getElementById("content");
$publish = document.getElementById("publish");
@@ -99,6 +115,80 @@ document.addEventListener('DOMContentLoaded', function() {
chrome.runtime.sendMessage({msg: $content.value});
});
});

document.getElementById('sync').addEventListener('click', function(e) {
e.preventDefault();
var posts = JSON.parse(H.get('posts', '[]'));
var p = "There ";
p += ((posts.length==1?'is ':'are ') + posts.length + " post" + (posts.length==1?'':'s'));
var thePosts = posts.length == 1 ? 'it' : 'them';
p += " saved on this computer.\n\nSyncing "+thePosts+" to your account gives you access to "+thePosts+" from anywhere. Sync now?";
if (!confirm(p)) {
return;
}

var $sync = this;
$sync.innerText = "Syncing now...";
$sync.className = 'disabled';

var http = new XMLHttpRequest();
var params = [];
for (var i=0; i<posts.length; i++) {
params.push({id: posts[i].id, token: posts[i].token});
}
http.open("POST", "https://write.as/api/posts/claim", true);
http.setRequestHeader("Content-type", "application/json");
http.onreadystatechange = function() {
if (http.readyState == 4) {
$sync.innerText = 'Importing now...';
if (http.status == 200) {
var res = JSON.parse(http.responseText);
if (res.data.length > 0) {
if (res.data.length != posts.length) {
// TODO: handle this serious situation
console.error("Request and result array length didn't match!");
return;
}
for (var i=0; i<res.data.length; i++) {
if (res.data[i].code == 200 || res.data[i].code == 404) {
// Post successfully claimed.
for (var j=0; j<posts.length; j++) {
// Find post in local store
var id = res.data[i].id;
if (typeof res.data[i].post !== 'undefined') {
id = res.data[i].post.id;
}
if (posts[j].id == id) {
// Remove this post
posts.splice(j, 1);
break;
}
}
} else {
for (var j=0; j<posts.length; j++) {
// Find post in local store
if (posts[j].id == res.data[i].id) {
// Note the error in the local post
posts[j].error = res.data[i].error_msg;
break;
}
}
}
}
H.set('posts', JSON.stringify(posts));
$sync.innerText = 'Synced.';
}
} else {
// TODO: show error visually (option to retry)
console.error("Well that didn't work at all!");
$sync.className = '';
$sync.innerText = 'Sync...';
}
}
};
http.send(JSON.stringify(params));
});
}

// bind publish action
@@ -122,13 +212,40 @@ document.addEventListener('DOMContentLoaded', function() {
// load font setting
H.load(fontRadios, 'font');
$content.className = fontRadios.value;
setPublishText(fontRadios.value, false);
// bind font changing action
for(var i = 0; i < fontRadios.length; i++) {
fontRadios[i].onclick = function() {
$content.className = this.value;
setPublishText(this.value, false);
H.save(fontRadios, 'font');
};
}

var handleRegUser = function() {
var http = new XMLHttpRequest();
http.open("GET", "https://write.as/api/me/", true);
http.onreadystatechange = function() {
if (http.readyState == 4) {
data = JSON.parse(http.responseText);
data = data.data;
if (typeof data.username !== 'undefined' && data.username != "") {
var $accTools = document.getElementById("account-tools")
$accTools.style.display = 'block';
var posts = JSON.parse(H.get('posts', '[]'));
if (posts.length > 0) {
document.getElementById('sync').style.display = 'inline';
} else {
document.getElementById('sync').style.display = 'none';
}
//document.getElementById("sync-count").innerText = posts.length + " post" + (posts.length==1?'':'s');
document.getElementById("username").innerText = data.username;
}
}
}
http.send();
}
handleRegUser();
if (H.get('updatedPostsMeta', '') == '') {
// Add metadata used by Pad to all saved posts


Loading…
Cancel
Save