Compare commits
7
Commits
1.0
..
submissions/1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0cc7a767e3 | ||
|
|
e90e394325 | ||
|
|
a631d8be28 | ||
|
|
2cefb5354e | ||
|
|
98d8f93174 | ||
|
|
3402e84419 | ||
|
|
77734cfbe8 |
No files matched your search
@@ -1 +1,3 @@
|
||||
BuildResults
|
||||
.project
|
||||
.settings
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"id": "com.palm.calculator",
|
||||
"id": "com.palm.app.calculator",
|
||||
"version": "3.0.1300",
|
||||
"vendor": "HP",
|
||||
"type": "web",
|
||||
@@ -9,4 +9,4 @@
|
||||
"splashicon": "icon-256x256.png",
|
||||
"uiRevision": "2",
|
||||
"removable": false
|
||||
}
|
||||
}
|
||||
@@ -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="../../../enyo/0.10/framework/enyo.js" launch="nobridge&nodebug"></script>
|
||||
<script type="text/javascript" src="/usr/palm/frameworks/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="../../../../enyo/0.10/framework/enyo.js" launch="nobridge"></script>
|
||||
<script type="text/javascript" src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" launch="nobridge"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript" src="Reminder.js"></script>
|
||||
|
||||
@@ -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="../../enyo/0.10/framework/enyo.js" launch="nobridge&nodebug"></script>
|
||||
<script type="text/javascript" src="/usr/palm/frameworks/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
|
||||
@@ -19,7 +19,7 @@ limitations under the License.
|
||||
<html>
|
||||
<head>
|
||||
<title>Contacts</title>
|
||||
<script src="../../enyo/0.10/framework/enyo.js" type="text/javascript"></script>
|
||||
<script src="/usr/palm/frameworks/enyo/0.10/framework/enyo.js" type="text/javascript"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
@@ -21,7 +21,7 @@ limitations under the License.
|
||||
<title>Jasmine Test Runner</title>
|
||||
|
||||
<!-- MODIFY ACCORDINGLY TO *LOCAL* ENYO SOURCE FILE -->
|
||||
<script src="../../enyo/0.10/framework/enyo.js" type="text/javascript"></script>
|
||||
<script src="/usr/palm/frameworks/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">
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
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 */
|
||||
]
|
||||
}
|
||||
]},
|
||||
|
||||
@@ -27,6 +27,5 @@ enyo.depends(
|
||||
"source/Composition.js",
|
||||
"source/EmailRecipient.js",
|
||||
"../controls/",
|
||||
"../css/compose.css",
|
||||
"/usr/palm/frameworks/caja/html-sanitizer-minified.js"
|
||||
"../css/compose.css"
|
||||
);
|
||||
@@ -312,11 +312,12 @@ 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);
|
||||
}
|
||||
|
||||
@@ -916,5 +917,10 @@ 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,"");
|
||||
}
|
||||
});
|
||||
@@ -33,6 +33,7 @@ enyo.depends(
|
||||
"source/Folders.js",
|
||||
"source/Mail.js",
|
||||
"source/MessagePane.js",
|
||||
"source/HtmlView.js",
|
||||
"source/MessageDisplay.js",
|
||||
"source/MessageLoader.js",
|
||||
"source/DarkSwipeable.js",
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
// @@@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,8 +51,10 @@ 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: [
|
||||
@@ -141,6 +143,7 @@ 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"},
|
||||
@@ -157,6 +160,7 @@ 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"}
|
||||
@@ -628,15 +632,19 @@ 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) {
|
||||
|
||||
@@ -841,7 +849,7 @@ enyo.kind({
|
||||
}
|
||||
},
|
||||
|
||||
mousedownHandler: function (sender, event) {
|
||||
/* mousedownHandler: function (sender, event) {
|
||||
return this.forwardMouseEventToBody(event);
|
||||
},
|
||||
|
||||
@@ -862,7 +870,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,
|
||||
@@ -883,10 +891,11 @@ 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;
|
||||
},
|
||||
@@ -900,6 +909,14 @@ 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'
|
||||
});
|
||||
Reference in new issue
Block a user