24 Commits
Author SHA1 Message Date
Suresh Arumugam aea5728e92 Merge pull request #4 from perezerah/master
README.md
2012-07-25 10:48:36 -07:00
tracy thorpe 1e98e8bd4e README.md update 2012-07-25 13:43:49 -04:00
tracy thorpe e3e7d19258 README file update 2012-07-24 17:30:14 -04:00
tracy thorpe 74e62a566e README.md update 2012-07-24 16:29:41 -04:00
Suresh Arumugam 5e61ec095e Merge pull request #3 from perezerah/master
Readme.md update
2012-07-24 10:51:06 -07:00
tracy thorpe bb1083f29c READme.md update 2012-07-23 19:41:36 -04:00
tracy thorpe 5ac4ad8d5a READme update 2012-07-23 19:28:25 -04:00
tracy thorpe ce8918f3c2 READme update 2012-07-23 19:16:25 -04:00
tracy thorpe a6abaef097 Readme update 2012-07-20 16:26:33 -04:00
Suresh Arumugam ebdbcd74ad Merge pull request #2 from perezerah/master
README.md
2012-07-18 14:59:23 -07:00
tracy thorpe 91d0a1488e Readme update 2012-07-18 17:54:18 -04:00
Suresh Arumugam 3328fdd806 Merge pull request #1 from perezerah/master
README.md
2012-07-18 14:51:03 -07:00
Tracy Thorpe a9067f9c1d Merge pull request #1 from openwebos/master
README.md
2012-07-18 13:11:39 -07:00
perezerah 0afa16ed63 Added README.md file 2012-07-17 14:52:41 -07:00
Nitika korla d631286fad Contacts app for OpenWebOS 2012-07-05 15:20:27 -07:00
Nitika korla 4c82dbaf53 Calendar app for OpenWebOS 2012-07-05 14:56:21 -07:00
sarumugam 3a4d1eb71f Merge branch 'master' of github.com:/openwebos/core-apps 2012-07-05 13:51:55 -07:00
sarumugam 35483d411a Adding Email and Accounts Apps 2012-07-05 13:51:01 -07:00
Nitika Korla 29b91ce6a6 Updated README.md file 2012-07-05 11:35:52 -07:00
Nitika Korla 2947803644 Added README.md file 2012-07-05 11:19:36 -07:00
sarumugam d9d621198f Replaced README.txt with README.md 2012-07-05 09:51:38 -07:00
sarumugam 3c2511ff61 Merge branch 'master' of github.com:/openwebos/core-apps 2012-07-05 09:43:59 -07:00
Nitika korla 866ea68950 Merge branch 'master' of github.com:openwebos/core-apps 2012-07-03 15:15:17 -07:00
Nitika korla 09124a1ea6 Clocl app for openWEBOS 2012-07-03 15:06:11 -07:00
16 changed files with 24 additions and 586 deletions

No files matched your search

-3
View File
@@ -1,3 +0,0 @@
BuildResults
.project
.settings
+1 -1
View File
@@ -18,7 +18,7 @@ See the License for the specific language governing permissions and
limitations under the License.
Quick Info
----------
-----------
Calculator Application for webOS. It was built using Enyo 1.0.
Core
+2 -2
View File
@@ -1,5 +1,5 @@
{
"id": "com.palm.app.calculator",
"id": "com.palm.calculator",
"version": "3.0.1300",
"vendor": "HP",
"type": "web",
@@ -9,4 +9,4 @@
"splashicon": "icon-256x256.png",
"uiRevision": "2",
"removable": false
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ limitations under the License.
<link rel="icon" type="image/png" href="images/icon.png">
<link rel="shortcut icon" type="image/png" href="images/icon.png">
<script type="text/javascript" src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" launch="nobridge&nodebug"></script>
<script type="text/javascript" src="../../../enyo/0.10/framework/enyo.js" launch="nobridge&nodebug"></script>
</head>
<body>
<script type="text/javascript" src="../libs/hacks.js"></script>
@@ -24,7 +24,7 @@ limitations under the License.
</script>
<title>Reminder</title>
<script type="text/javascript" src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" launch="nobridge"></script>
<script type="text/javascript" src="../../../../enyo/0.10/framework/enyo.js" launch="nobridge"></script>
</head>
<body>
<script type="text/javascript" src="Reminder.js"></script>
+2 -2
View File
@@ -32,11 +32,11 @@ limitations under the License.
<link rel="shortcut icon" type="image/png" href="images/icon.png">
<script type="text/javascript" src="/usr/palm/frameworks/mojoloader.js"></script>
<script type="text/javascript" src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" launch="nobridge&nodebug"></script>
<script type="text/javascript" src="../../enyo/0.10/framework/enyo.js" launch="nobridge&nodebug"></script>
</head>
<body>
<script type="text/javascript" src="libs/mock.js"></script>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
end
end
+1 -1
View File
@@ -19,7 +19,7 @@ limitations under the License.
<html>
<head>
<title>Contacts</title>
<script src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" type="text/javascript"></script>
<script src="../../enyo/0.10/framework/enyo.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
+1 -1
View File
@@ -21,7 +21,7 @@ limitations under the License.
<title>Jasmine Test Runner</title>
<!-- MODIFY ACCORDINGLY TO *LOCAL* ENYO SOURCE FILE -->
<script src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" type="text/javascript"></script>
<script src="../../enyo/0.10/framework/enyo.js" type="text/javascript"></script>
<!-- MODIFY ACCORDINGLY TO *LOCAL* JASMINE SOURCE FILES -->
<link rel="stylesheet" type="text/css" href="../../frameworks/jasmine/jasmine.css">
-7
View File
@@ -2,13 +2,6 @@
Email application for webOS. Written using enyo 1.0.
# Limitations and Known Issues
## User Credentials will be stored in clear format in the db8. Secure storing support will be added later.
## HTML Sanitizer function used in the Email display message view, is limited to remove only certain tags such as Script, iframe, object, embed. More generic solution is planned for post beta release.
# App launch lifecycle
The email app is launched automatically at boot. There is a headless window,
@@ -55,8 +55,8 @@ enyo.kind({
onChange: "accountTypeChanged",
items: [
{caption: $L("IMAP"), value: AccountWizard.IMAP},
{caption: $L("POP"), value: AccountWizard.POP}
/* {caption: $L("EAS"), value: AccountWizard.EAS} /* , showing: false */
{caption: $L("POP"), value: AccountWizard.POP},
{caption: $L("EAS"), value: AccountWizard.EAS} /* , showing: false */
]
}
]},
+2 -1
View File
@@ -27,5 +27,6 @@ enyo.depends(
"source/Composition.js",
"source/EmailRecipient.js",
"../controls/",
"../css/compose.css"
"../css/compose.css",
"/usr/palm/frameworks/caja/html-sanitizer-minified.js"
);
+2 -8
View File
@@ -312,12 +312,11 @@ enyo.kind({
if (this.composition.originalText) {
this.$.originalMessageBody.show();
/* var sanitized = html_sanitize(this.composition.sanitizeOriginalText(), function (url) {
var sanitized = html_sanitize(this.composition.sanitizeOriginalText(), function (url) {
return url;
}, function (id) {
return id;
});*/
var sanitized = this.sanitizeHtml(this.composition.sanitizeOriginalText());
});
this.$.originalMessageBody.setValue(sanitized);
}
@@ -917,10 +916,5 @@ enyo.kind({
this.$.missingRecipientsAlert.close();
this.$.badRecipientsAlert.close();
this.$.toInput.forceFocus();
},
sanitizeHtml: function (unsafeHtml) {
var rEx = new RegExp("<(script|object|embed|iframe)[^>]*>([\\S\\s]*?)<\/(script|object|embed|iframe)>", "gim");
return unsafeHtml.replace(rEx,"");
}
});
-1
View File
@@ -33,7 +33,6 @@ enyo.depends(
"source/Folders.js",
"source/Mail.js",
"source/MessagePane.js",
"source/HtmlView.js",
"source/MessageDisplay.js",
"source/MessageLoader.js",
"source/DarkSwipeable.js",
-529
View File
@@ -1,529 +0,0 @@
// @@@LICENSE
//
// Copyright (c) 2010-2012 Hewlett-Packard Development Company, L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// LICENSE@@@
enyo.kind({
name: "AbstractHtmlView",
kind: "Control",
events: {
onViewReady: "",
onLoadFailed: "",
onLinkClick: "",
onInspectElement: ""
},
published: {
cidMap: {},
allowRemoteContent: true
},
create: function () {
this.inherited(arguments);
},
// Returns true if the HtmlView is more or less ready and has content displayed
// The accuracy of this method may depend on the implementation.
isReady: function () {
return false;
},
activate: function () {
},
deactivate: function () {
},
});
enyo.kind({
name: "WebviewHtmlView",
kind: "AbstractHtmlView",
create: function () {
this.inherited(arguments);
this.webviewBodyLoaded = false;
},
destroy: function () {
// FIXME workaround for bug in webview
try {
this.inherited(arguments);
} catch (e) {
this.error(e);
}
},
createWebview: function () {
this.createComponent({
name: "webview",
kind: "WebView",
fitRender: false,
acceptCookies: false,
enableJavascript: false,
ignoreMetaTags: true,
onSingleTap: "webviewTap",
onUrlRedirected: "doLinkClick",
onLoadStarted: "webviewLoadStarted",
onLoadComplete: "webviewLoadComplete",
onLoadStopped: "webviewLoadStopped"
});
this.$.webview.render();
},
initWebview: function () {
if (!this.$.webview) {
this.createWebview();
this.setupWebview();
}
},
setupWebview: function () {
if (this._webviewReady) {
return;
}
this.$.webview.setRedirects([
{regex: "^file:.*", cookie: "", enable: false},
{regex: ".*", cookie: "", enable: true}
]);
// Hack to prevent double url loads
var origUrlChanged = viewControl.urlChanged.bind(viewControl);
viewControl.urlChanged = function (old) {
if (viewControl.url !== viewControl._pendingUrl) {
console.log("calling orig");
viewControl._pendingUrl = viewControl.url;
origUrlChanged(old);
}
};
var origLoadStarted = viewControl.loadStarted.bind(viewControl);
viewControl.loadStarted = function () {
viewControl._pendingUrl = undefined;
origLoadStarted();
}
this._webviewReady = true;
},
// [public]
loadUrl: function (url) {
this.initWebview();
this.$.webview.setUrl(url);
},
// [public]
activate: function () {
this.initWebview();
this.log("activating webview");
this.$.webview.activate();
},
// [public]
deactivate: function () {
if (this.$.webview) {
this.$.webview.activate();
}
},
webviewLoadStarted: function () {
console.log("load started");
this.webviewBodyLoaded = false;
},
webviewLoadComplete: function () {
this.loadTimer = window.setTimeout(this.webviewReady.bind(this), 1000);
},
webviewLoadStopped: function () {
console.log("load stopped");
this.webviewBodyLoaded = true;
this.webviewReady();
},
webviewReady: function () {
if (this.loadTimer) {
window.clearTimeout(this.loadTimer);
}
this.doViewReady();
},
webviewTap: function () {
// TODO
return true;
},
});
enyo.kind({
name: "InlineHtmlView",
kind: "AbstractHtmlView",
CID_REGEX: /^cid:/i,
CSS_RULE_REGEX: /\s*([-\w]+)\s*:\s*([^:;]*)?(;|$)/g,
CSS_UNSAFE_PROPERTY_REGEX: /(^-\w+)|behavior$/i,
CSS_URL_NOTATION_REGEX: /url\s*\(((?:\\.|.)*?)\)/i,
VALID_RESOURCE_URL_REGEX: /^https?:/i,
VALID_LINK_URL_REGEX: /^(https?|mailto):/i,
create: function () {
this.inherited(arguments);
},
// TODO: make this take a callback since both loading and sanitizing may be asynchronous later
loadAndSanitize: function (url, contentType) {
url = url.replace("file://", "");
var unsafeData = palmGetResource(url);
return this.loadedAndSanitize(unsafeData, contentType);
},
loadedAndSanitize: function(unsafeData, contentType) {
// This will get set to true if checkAllowExternalResource blocks a url
this.remoteContentWasBlocked = false;
var isHtml = (contentType.toLowerCase() == "text/html");
// FIXME currently very slow for some emails
var cleanHtml = isHtml ? this.sanitizeHtml(unsafeData) : this.sanitizeText(unsafeData);
return cleanHtml;
},
// Returns true if a remote content url (e.g. external image) was blocked from being displayed
wasRemoteContentBlocked: function () {
return this.remoteContentWasBlocked;
},
// Check whether a url can be loaded in an image tag or css style
checkAllowExternalResource: function (url) {
if (!this.allowRemoteContent) {
this.remoteContentWasBlocked = true;
return false;
}
return this.VALID_RESOURCE_URL_REGEX.test(url);
},
// Check whether a link can be referenced
checkAllowLink: function (url) {
return this.VALID_LINK_URL_REGEX.test(url);
},
// Check if this external url is allowed
mapUrl: function (url, tagName, attribName) {
if (this.CID_REGEX.test(url)) {
// replace cid: reference with local file path
return this.cidMap[url.substr(4)] || "";
}
if (tagName === "a" && attribName === "href") {
return this.checkAllowLink(url) ? url : null;
} else if (tagName === "img" && attribName === "src") {
return this.checkAllowExternalResource(url) ? url : null;
} else {
return null;
}
},
// Checks and possibly removes external urls in inline css styles
// TODO: TEST
mapInlineStyle: function (style) {
var self = this;
var cleanStyle = "";
// Extract css rules one-by-one to make sure there's nothing tricky
var rule = new RegExp(this.CSS_RULE_REGEX); // copy for repeated matches
var m;
while (!!(m = rule.exec(style))) {
var name = m[1];
var value = m[2];
if (!name || !value || this.CSS_UNSAFE_PROPERTY_REGEX.exec(name)) {
// unsafe css property
continue;
}
// Cleanup urls
value = value.replace(self.CSS_URL_NOTATION_REGEX, function (s, match1) {
return self.checkAllowExternalResource(match1) ? s : "url()";
});
// Append normalized css
cleanStyle += name + ":" + value + ";";
}
return cleanStyle;
},
/*sanitizeHtml: function (unsafeHtml) {
var cidMap = this.cidMap;
return HtmlSanitizer.sanitize(unsafeHtml,
this.mapUrl.bind(this),
this.mapInlineStyle.bind(this)
);
},*/
sanitizeHtml: function (unsafeHtml) {
var rEx = new RegExp("<(script|object|embed|iframe)[^>]*>([\\S\\s]*?)<\/(script|object|embed|iframe)>", "gim");
return unsafeHtml.replace(rEx,"");
},
sanitizeText: function (unsafeText) {
var text = enyo.string.escapeHtml(unsafeText);
text = text.replace(/\r\n|\n|\r/g, "<br>");
// TODO: more sophisticated text formatting
return text;
}
});
enyo.kind({
name: "DivHtmlView",
kind: "InlineHtmlView",
className: "divhtmlview",
components: [
/* clipbox lets us explicitly size the content (based on scaling calculations) */
{name: "clipbox", className: "divhtmlview-clipbox", components: [
/* contents of the HTML area */
{name: "wrapper", allowHtml: true /* must sanitize */, onclick: "wrapperClick", onmouseup: "wrapperMouseup", requiresDomClick: true, className: "divhtmlview-wrapper selectable"}
]}
],
mixins: [
enyo.sizeableMixin
],
published: {
zoom: 1.0,
url: null
},
create: function () {
this.inherited(arguments);
this.viewReady = false;
},
rendered: function () {
this.inherited(arguments);
this.clipboxNode = this.$.clipbox.hasNode();
this.wrapperNode = this.$.wrapper.hasNode();
},
isReady: function () {
return this.viewReady;
},
// [public]
loadUrl: function (url, contentType) {
if (!url) {
this.log("no url provided");
return;
}
this.url = url;
this.contentType = contentType || "text/plain";
if(window.PalmSystem) {
enyo.asyncMethod(this, enyo.bind(this, "loadPage"));
}
else {
enyo.xhr.request({
url: url,
method: "GET",
callback: enyo.bind(this, "loadPage")
});
}
},
activate: function () {
},
deactivate: function () {
},
loadPage: function (inSender, inResponse) {
var cleanHtml;
if(window.PalmSystem) {
cleanHtml = this.loadAndSanitize(this.url, this.contentType);
}
else {
if(!inResponse || inResponse.responseText === '') {
cleanHtml = $L("Error opening email.");
}
else {
cleanHtml = this.loadedAndSanitize(inResponse.responseText, this.contentType);
}
}
this.$.wrapper.setContent(cleanHtml);
this.fitWidth();
this.viewReady = true;
this.doViewReady();
},
fitWidth: function () {
var viewWidth = this.hasNode().clientWidth;
var contentWidth = this.wrapperNode.scrollWidth;
if (contentWidth > viewWidth) {
this.setZoom(viewWidth / contentWidth);
}
},
// start pinch zoom
gesturestartHandler: function (sender, e) {
this.centeredZoomStart(e);
},
// pinch zoom
gesturechangeHandler: function (sender, e) {
var gi = this.centeredZoomChange(e);
// Change zoom if greater than some threshold to prevent jitter
var delta = Math.abs(gi.zoom - this.zoom);
if (delta >= 0.08) {
this.setZoom(gi.zoom);
//this.setScrollPositionDirect(gi.x, gi.y);
}
},
// end pinch zoom
gestureendHandler: function (sender, e) {
},
getMinZoom: function () {
// calculate every time in case the size changes
var viewWidth = this.hasNode().clientWidth;
var contentWidth = this.wrapperNode.scrollWidth;
return Math.max(0.3, viewWidth / contentWidth);
},
getMaxZoom: function () {
return 1.0;
},
// hacky support for old versions of enyo
calcZoomOffset: function() {
return {left: 0, top: 0};
},
getZoomRect: function () {
var contentHeight = this.wrapperNode.scrollHeight;
var contentWidth = this.wrapperNode.scrollWidth;
return {
left: 0,
top: 0,
width: contentHeight * this.zoom,
height: contentWidth * this.zoom
};
},
zoomChanged: function () {
var contentWidth = this.wrapperNode.scrollWidth;
var contentHeight = this.wrapperNode.scrollHeight;
this.zoom = Math.max(this.getMinZoom(), Math.min(this.zoom, this.getMaxZoom()));
//console.log("setting zoom to " + this.zoom);
this.$.wrapper.applyStyle("-webkit-transform", "scale(" + this.zoom + ")");
this.$.wrapper.applyStyle("-webkit-transform-origin", "0 0");
// Change the size of the container to match the scaled size
this.$.clipbox.applyStyle("width", Math.ceil(this.zoom * contentWidth) + "px");
this.$.clipbox.applyStyle("height", Math.ceil(this.zoom * contentHeight) + "px");
},
mouseholdHandler: function (sender, event) {
var props = this.findLinkOrImageProperties(event.target, this.hasNode());
if (props) {
//console.log("mouse hold on link or image: " + JSON.stringify(props));
this.doInspectElement(event, props);
return true;
}
},
wrapperMouseup: function(sender, event) {
// Need to record if there was a drag
this.didDrag = event.didDrag;
},
wrapperClick: function(sender, event) {
// Check if there was a drag
// NOTE: Can't use event.didDrag because it gets cleared during the mouseup
if (this.didDrag) {
this.didDrag = false;
// Don't click if there was a drag
event.preventDefault();
return true;
}
var props = this.findLinkOrImageProperties(event.target, this.wrapperNode);
var url = props && props.linkUrl;
if (url) {
this.doLinkClick(url, event);
event.preventDefault();
return true;
}
},
// find link and/or image (may be both)
findLinkOrImageProperties: function (inNode, inAncestor) {
var props = undefined;
var n = inNode;
while (n && n != inAncestor) {
var tagLower = n.tagName.toLowerCase();
if (tagLower === "a" && n.href) {
props = props || {};
props.linkUrl = n.href;
// exit when we see an anchor tag
break;
} else if (tagLower === "img" && n.src) {
props = props || {};
props.imageSrc = n.src;
// keep searching for an anchor tag
}
n = n.parentNode;
}
return props;
}
});
@@ -38,7 +38,7 @@ enyo.kind({
// Email Body Content starts here
// this sauce is weak. So weak.
/*((window.fauxMail || !window.PalmSystem) ?
((window.fauxMail || !window.PalmSystem) ?
// FAKE webview
{name: "body", kind: "Control", nodeTag: "pre", flex: 1, className: "mail-body", resize: function () {
},
@@ -51,10 +51,8 @@ enyo.kind({
onAlertDialog: "alertDialogHandler", onConfirmDialog: "confirmDialogHandler", onPromptDialog: "promptDialogHandler",
onSSLConfirmDialog: "SSLConfirmDialogHandler"
}
),*/
),
// This goes second, even though it is displayed first, in order to float over the webview
{kind:"Scroller", flex:1, style:"height:1000px;", components:[
{name: "mailHeaderUnit", components: [
{name: "header", className: "body-header", components: [
{name: "bodyStamp", className: "body-stamp", components: [
@@ -143,7 +141,6 @@ enyo.kind({
]}
]},
// end email header
{name: "body", kind: "DivHtmlView", showing: true, onViewReady: "viewReady", onLinkClick: "openLink"},
{name: "messageErrors", kind: "Pane", showing: false, flex: 1, components: [
{name: "downloadError", className: "body-placeholder", style: "text-align: center; background:white;", pack: "center", kind: "VFlexBox", components: [
{kind: "Image", src: "../images/list-error.png"},
@@ -160,7 +157,6 @@ enyo.kind({
]}
]}
]}, // end mail header unit
]},
{name: "appMgrOpen", method: "open", kind: "enyo.PalmService", service: enyo.palmServices.application},
{name: "pseudoDetails", kind: "com.palm.library.contactsui.detailsDialog", onCancelClicked: "closePseudoDetails"},
{name: "webviewContextMenu", kind: "PopupSelect", onSelect: "webviewContextMenuSelect"}
@@ -632,19 +628,15 @@ enyo.kind({
},
setBody: function (email, isQuoting) {
/*if (this.$.body.setHTML) { // i.e., a real WebView, which we use onDevice
if (this.$.body.setHTML) { // i.e., a real WebView, which we use onDevice
var body = email.getBodyPart();
var html = this._buildMessageHTML(body.path, body.mimeType, isQuoting);
//this.$.body.setHTML("file:///email-local-content.html", html);
this.$.body.setHTML("file:///email-local-content.html", html);
this.resize();
} else {
this.$.body.setContent(email.data.summary);
}*/
var body = email.getBodyPart();
this.$.body.loadUrl("file://" + body.path, body.mimeType);
}
},
_buildMessageHTML: function (path, mimeType, replyOrForward) {
@@ -849,7 +841,7 @@ enyo.kind({
}
},
/* mousedownHandler: function (sender, event) {
mousedownHandler: function (sender, event) {
return this.forwardMouseEventToBody(event);
},
@@ -870,7 +862,7 @@ enyo.kind({
// Hack to call flick handler in header on body
// FIXME should pass event instead?
return this.$.body.$.view.flickHandler(sender, event);
},*/
},
headerResized: function (sender, event) {
var view = this.$.body,
@@ -891,11 +883,10 @@ enyo.kind({
}
},
resize: function () {
/*this.headerResized();
this.headerResized();
if (this.$.body.resize) {
this.$.body.resize();
}*/
}
this.resized(); // provided by enyo. needed for vertical reflow
this._doingNestedScroll = undefined;
},
@@ -909,14 +900,6 @@ enyo.kind({
]);
}
},
openLink: function (sender, url) {
// TODO remove this logging
this.log("### Opening URL", url);
// Launch default app for handling this url
this.$.appMgrOpen.call({target: url, subscribe: false});
},
DEFAULT_SENDER_IMAGE: '../images/detail_avatar.png'
});