This was is a good one and has been doing my head in!
I had a user mailbox that could log in to OWA but not Outlook.
With outlook you would get an error saying:
"Cannot open your default e-mail folders. Microsoft Exchange is not available. Ether there are network problems or the exchange Computer is down for maintenance"
If you run:
Get-LogonStatistics -Identity <email address>
Then have a look at the FullMailboxDirectoryName
This should match the users legacyexchangedn. In my case, another user has the same address as a proxy address.
An update to an old script. Essentially I have added a switch for activation preference, so you can fail all databases over to say Activation Preference #3.
Copy below and save to Rehome-DatabaseActivationPreference.ps1. Then run say:
So playing around with PowerShell over the weekend, doing some Web, SQL and Exchange stuff, when I thought .. Would it be great if I could call PowerShell commands from an ASP page!
It quite cool! Once I worked out the syntax and how things fitted together it was quite simple.
Meet Get-TransportQueue.ps1x. You need to have the Exchange Server 2010 Management Tools installed on the server to install PowerShell ASP on. The copy the code below and access the webpage .. how sweet is that! I think I found an “undocumented feature” with variable names that are very similar but it work a treat, What is a shame is that the page doesn’t dynamically draw as code is executed .. instead it’s all rendered once comple!
Next step will be user provisioning tool. (in theory anyway). Let me know what you think of the code.
</body> < script type=’text/javascript’> // Wrapped in a function so as to not pollute the global scope. var activatables = (function () { // The CSS classes to use for active/inactive elements. var activeClass = ‘active’; var inactiveClass = ‘inactive’;
var anchors = {}, activates = {}; var regex = /#([A-Za-z][A-Za-z0-9:._-]*)$/;
// Find all anchors (<a href=’#something’>.) var temp = document.getElementsByTagName(‘a’); for (var i = 0; i < temp.length; i++) { var a = temp[i];
// Make sure the anchor isn’t linking to another page. if ((a.pathname != location.pathname && ‘/’ + a.pathname != location.pathname) || a.search != location.search) continue;
// Make sure the anchor has a hash part. var match = regex.exec(a.href); if (!match) continue; var id = match[1];
// Add the anchor to a lookup table. if (id in anchors) anchors[id].push(a); else anchors[id] = [a]; }
// Adds/removes the active/inactive CSS classes depending on whether the // element is active or not. function setClass(elem, active) { var classes = elem.className.split(/s+/); var cls = active ? activeClass : inactiveClass, found = false; for (var i = 0; i < classes.length; i++) { if (classes[i] == activeClass || classes[i] == inactiveClass) { if (!found) { classes[i] = cls; found = true; } else { delete classes[i–]; } } }
if (!found) classes.push(cls); elem.className = classes.join(‘ ‘); }
// Functions for managing the hash. function getParams() { var hash = location.hash || ‘#’; var parts = hash.substring(1).split(‘&’);
var params = {}; for (var i = 0; i < parts.length; i++) { var nv = parts[i].split(‘=’); if (!nv[0]) continue; params[nv[0]] = nv[1] || null; }
return params; }
function setParams(params) { var parts = []; for (var name in params) { // One of the following two lines of code must be commented out. Use the // first to keep empty values in the hash query string; use the second // to remove them. //parts.push(params[name] ? name + ‘=’ + params[name] : name); if (params[name]) parts.push(name + ‘=’ + params[name]); }
// Looks for changes to the hash. var knownHash = location.hash; function pollHash() { var hash = location.hash; if (hash != knownHash) { var params = getParams(); for (var name in params) { if (!(name in activates)) continue; activates[name](params[name]); } knownHash = hash; } } setInterval(pollHash, 250);
function getParam(name) { var params = getParams(); return params[name]; }
function setParam(name, value) { var params = getParams(); params[name] = value; setParams(params); }
// If the hash is currently set to something that looks like a single id, // automatically activate any elements with that id. var initialId = null; var match = regex.exec(knownHash); if (match) { initialId = match[1]; }
// Takes an array of either element IDs or a hash with the element ID as the key // and an array of sub-element IDs as the value. // When activating these sub-elements, all parent elements will also be // activated in the process. function makeActivatable(paramName, activatables) { var all = {}, first = initialId;
// Activates all elements for a specific id (and inactivates the others.) function activate(id) { if (!(id in all)) return false;
for (var cur in all) { if (cur == id) continue; for (var i = 0; i < all[cur].length; i++) { setClass(all[cur][i], false); } }
for (var i = 0; i < all[id].length; i++) { setClass(all[id][i], true); }
setParam(paramName, id);
return true; }
activates[paramName] = activate;
function attach(item, basePath) { if (item instanceof Array) { for (var i = 0; i < item.length; i++) { attach(item[i], basePath); } } else if (typeof item == ‘object’) { for (var p in item) { var path = attach(p, basePath); attach(item[p], path); } } else if (typeof item == ‘string’) { var path = basePath ? basePath.slice(0) : []; var e = document.getElementById(item); if (e) path.push(e); else return;
if (!first) first = item;
// Store the elements in a lookup table. all[item] = path;
// Attach a function that will activate the appropriate element // to all anchors. if (item in anchors) { // Create a function that will call the ‘activate’ function with // the proper parameters. It will be used as the event callback. var func = (function (id) { return function (e) { activate(id);
if (!e) e = window.event; if (e.preventDefault) e.preventDefault(); e.returnValue = false; return false; }; })(item);
for (var i = 0; i < anchors[item].length; i++) { var a = anchors[item][i];
getFavIconUrl : function() {
var links = document.getElementsByTagName("link");
var i;
for (i = 0; i < links.length; i++) {
if (links[i].rel) {
var rels = links[i].rel.toLowerCase().split(/s+/);
if (Evernote.ArrayExtension.indexOf(rels, "icon") !== -1) {
// Found it!
return links[i].href;
}
}
}
//Try to get it from google web site
var re = new RegExp( "^[^:]+:/+([^/" + ":" + "]+).*$" );
var domain = PageContext.url.replace( re, "$1" );
return "http://www.google.com/s2/favicons?domain=" + domain.toLowerCase();
},
injectAdditionalTags : function() {
var url = document.location.href;
if ( url.match( /^https?://[a-z0-9-+.]*(evernote|yinxiang).com//i ) ) {
try {
var metas = document.getElementsByTagName( "meta" );
for ( var i = 0; i // // <![CDATA[
/*! jQuery v1.7.2 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("”).appendTo(b),e=d.css(“display”);d.remove();if(e===”none”||e===””){ck||(ck=c.createElement(“iframe”),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?””:””)+””),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,”display”),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject(“Microsoft.XMLHTTP”)}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e0){if(c!==”border”)for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+”defer”,e=b+”queue”,g=b+”mark”,h=f._data(a,d);h&&(c===”queue”||!f._data(a,e))&&(c===”mark”||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b===”data”&&f.isEmptyObject(a[b]))continue;if(b!==”toJSON”)return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e=”data-“+c.replace(k,”-$1″).toLowerCase();d=a.getAttribute(e);if(typeof d==”string”){try{d=d===”true”?!0:d===”false”?!1:d===”null”?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*()[^>]*$|#([w-]*)$)/,j=/S/,k=/^s+/,l=/s+$/,m=/^(?:)?$/,n=/^[],:{}s]*$/,o=/\(?:[“\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/”[^”\nr]*”|true|false|null|-?d+(?:.d*)?(?:[eE][+-]?d+)?/g,q=/(?:^|:|,)(?:s*[)+/g,r=/(webkit)[ /]([w.]+)/,s=/(opera)(?:.*version)?[ /]([w.]+)/,t=/(msie) ([w.]+)/,u=/(mozilla)(?:.*? rv:([w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+””).toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a===”body”&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a==”string”){a.charAt(0)!==””||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.select
or+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,–j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger(“ready”).off(“ready”)}},bindReady:function(){if(!A){A=e.Callbacks(“once memory”);if(c.readyState===”complete”)return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener(“DOMContentLoaded”,B,!1),a.addEventListener(“load”,e.ready,!1);else if(c.attachEvent){c.attachEvent(“onreadystatechange”,B),a.attachEvent(“onload”,e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)===”function”},isArray:Array.isArray||function(a){return e.type(a)===”array”},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||”object”},isPlainObject:function(a){if(!a||e.type(a)!==”object”||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,”constructor”)&&!D.call(a.constructor.prototype,”isPrototypeOf”))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!=”string”||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,”@”).replace(p,”]”).replace(q,””)))return(new Function(“return “+b))();e.error(“Invalid JSON: “+b)},parseXML:function(c){if(typeof c!=”string”||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,”text/xml”)):(d=new ActiveXObject(“Microsoft.XMLDOM”),d.async=”false”,d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName(“parsererror”).length)&&e.error(“Invalid XML: “+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,”ms-“).replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test("Â ")&&(k=/^[sxA0]+/,l=/[sxA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l–,f<=m&&m–),c.splice(f–,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,–g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):–g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML="
a“,d=p.getElementsByTagName(“*”),e=p.getElementsByTagName(“a”)[0];if(!d||!d.length||!e)return{};g=c.createElement(“select”),h=g.appendChild(c.createElement(“option”)),i=p.getElementsByTagName(“input”)[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName(“tbody”).length,htmlSerialize:!!p.getElementsByTagName(“link”).length,style:/top/.test(e.getAttribute(“style”)),hrefNormalized:e.getAttribute(“href”)===”/a”,opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value===”on”,optSelected:h.selected,getSetAttribute:p.className!==”t”,enctype:!!c.createElement(“form”).enctype,html5Clone:c.createElement(“nav”).cloneNode(!0).outerHTML!==””,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode===”CSS1Compat”,i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent(“onclick”,function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent(“onclick”)),i=c.createElement(“input”),i.value=”t”,i.setAttribute(“type”,”radio”),b.radioValue=i.value===”t”,i.setAttribute(“checked”,”checked”),i.setAttribute(“name”,”t”),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m=”on”+n,o=m in p,o||(p.setAttribute(m,”return;”),o=typeof p[m]==”function”),b[n+”Bubbles”]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName(“body”)[0];!u||(m=1,t=”padding:0;margin:0;border:”,r=”position:absolute;top:0;left:0;width:1px;height:1px;”,s=t+”0;visibility:hidden;”,n=”style='”+r+t+”5px solid #000;”,q=”
// is what we found any good?
// ==========================
switch (true)
{
case ($R.getContent__find__hasIsolatedTitleInHTML(_aboveHTML)):
case (_differentTargets && (_aboveHTML.split(‘<a ').length < 3) && ($R.measureText__getTextLength(_aboveHTML.replace(/]+?>/gi, ”).replace(/s+/gi, ‘ ‘)) ”); else
{
// if all else failed, get document title
// ======================================
// loop through pregs
// ==================
for (var i=0, _i=_doc_title_pregs.length; i 1) { break; }
}
// sort title parts — longer goes higher up — i.e. towards 0
// ================
_doc_title_parts.sort(function (a, b)
{
switch (true)
{
case (a.length > b.length): return -1;
case (a.length 1 ? _doc_title_parts[0] : _documentTitle)
+ $R.articleTitleMarker__end
// vars
// ====
$R.debugStuff = [];
$R.debugTimers = [];
// write log
// =========
$R.initializeWriteLogFunction = function ()
{
switch (true)
{
case (!(!($R.win.console && $R.win.console.log))):
$R.writeLog = function (msg) { $R.win.console.log(msg); };
break;
case (!(!($R.win.opera && $R.win.opera.postError))):
$R.writeLog = function (msg) { $R.win.opera.postError(msg); };
break;
default:
$R.writeLog = function (msg) {};
break;
}
};
// log
// ===
$R.initializeWriteLogFunction();
$R.log = function ()
{
if ($R.debug); else { return; }
for (var i=0, il=arguments.length; i ”)):
case (_element.tagName.toLowerCase() == ‘onject’):
case (_element.tagName.toLowerCase() == ’embed’):
return;
}
$R.sel.getWindowFromDocument = function (theDocument)
{
if (theDocument); else { return null; }
if (‘defaultView’ in theDocument) {
arguments.calee = function (theDocument) {
if (theDocument); else { return null; }
return theDocument.defaultView;
};
}
else if (‘parentWindow’ in theDocument) {
arguments.calee = function (theDocument) {
if (theDocument); else { return null; }
return theDocument.parentWindow;
};
}
else {
arguments.calee = function (theDocument) {
return null;
};
}
return arguments.calee(theDocument);
};
$R.sel.getSelection = function (theWindow)
{
if (theWindow); else { return null; }
if (‘getSelection’ in theWindow) {
arguments.calee = function (theWindow) {
if (theWindow); else { return null; }
return theWindow.getSelection();
};
}
else if (‘selection’ in theWindow.document) {
arguments.calee = function (theWindow) {
if (theWindow); else { return null; }
return theWindow.document.selection;
};
}
else {
arguments.calee = function (theWindow) {
return null;
};
}
return arguments.calee(theWindow);
};
$R.sel.getRange = function (selection)
{
if (selection); else { return null; }
if (‘getRangeAt’ in selection) {
arguments.calee = function (selection) {
if (selection); else { return null; }
if (selection.rangeCount > 0) { return selection.getRangeAt(0); }
else { return null; }
// doesn’t work in old versions of safari
// … I don’t care
};
}
else if (‘createRange’ in selection) {
arguments.calee = function (selection) {
if (selection); else { return null; }
return selection.createRange();
};
}
else {
arguments.calee = function (selection) {
return null;
};
}
return arguments.calee(selection);
};
$R.sel.getRangeHTML = function (range)
{
if (range); else { return null; }
if (‘htmlText’ in range) {
arguments.calee = function (range) {
if (range); else { return null; }
return range.htmlText;
};
}
else if (‘surroundContents’ in range) {
arguments.calee = function (range) {
if (range); else { return null; }
var dummy = range.commonAncestorContainer.ownerDocument.createElement(“div”);
dummy.appendChild(range.cloneContents());
return dummy.innerHTML;
};
}
else {
arguments.calee = function (range) {
return null;
};
}
return arguments.calee(range);
};
$R.sel.getRangeText = function (range)
{
if (range); else { return null; }
if (‘text’ in range) {
arguments.calee = function (range) {
if (range); else { return null; }
return range.text;
};
}
else if (‘surroundContents’ in range) {
arguments.calee = function (range) {
if (range); else { return null; }
var dummy = range.commonAncestorContainer.ownerDocument.createElement(“div”);
dummy.appendChild(range.cloneContents());
return dummy.textContent;
};
}
else {
arguments.calee = function (range) {
return null;
};
}
// link
// ====
case (_tag_name == ‘a’):
var _href = “”;
try {
_href = _node.href;
} catch(e) {
Evernote.Logger.warn(“Clearly: failed to get href of link element” + e);
}
// sanity
if (_href > ”); else { break; }
if (_href.indexOf); else { break; }
_result._is__link = true;
// skip
for (var i=0, _i=$R.skipStuffFromDomains__links.length; i -1)
{ _result._is__link_skip = true; break; }
}
// inside link
if (_global__inside_link); else
{
_global__inside_link = true;
_global__inside_link__element_index = _result.__index;
}
// done
_return__links.push(_result);
break;
// image
// =====
case (_tag_name == ‘img’):
// skip
// ====
if (_node.src && _node.src.indexOf)
{
for (var i=0, _i=$R.skipStuffFromDomain__images.length; i -1)
{ _result._is__image_skip = true; break; }
}
}
// special case for body — if it was just skipped
// =====================
if ((_result.__index == 1) && !(_result._is__candidate))
{
_result._is__candidate = true;
_result._is__bad = true;
_return__candidates.push(_result);
}
}
}
// return
// ======
return _result;
};
// actually do it
// ==============
_recursive(_nodeToExplore);
// just exploring — return first thing
// ==============
if (_justExploring) { return _return__containers.pop(); }
$R.getContent__processCandidates = function (_candidatesToProcess)
{
// process this var
// ================
var _candidates = _candidatesToProcess;
// sort _candidates — the lower in the dom, the closer to position 0
// ================
_candidates.sort(function (a, b)
{
switch (true)
{
case (a.__index b.__index): return 1;
default: return 0;
}
});
// get first
// =========
var _main = _candidates[0]
if ($R.debug) { $R.log(‘should be body’, _main, _main.__node); }
// pieces of text
// and points computation
// ======================
for (var i=0, _i=_candidates.length; i<_i; i++)
{
// pieces
// ======
var
_count__pieces = 0,
_array__pieces = []
;
for (var k=i, _k=_candidates.length; k 0) { continue; }
if ($.contains(_candidates[i].__node, _candidates[k].__node)); else { continue; }
// store piece, if in debug mode
if ($R.debug) { _array__pieces.push(_candidates[k]); }
// sort _candidates — the more points, the closer to position 0
// ================
_candidates.sort(function (a, b)
{
switch (true)
{
case (a.__points > b.__points): return -1;
case (a.__points 250)
;
// negative
if (_points_history[0] 0)):
case (!($.contains(_main.__node, _element.__node))):
return null;
default:
return _element;
}
});
// add main – to amke sure the result is never blank
_candidates.unshift(_main);
// sort _candidates — the lower in the dom, the closer to position 0
// ================
_candidates.sort(function (a, b)
{
switch (true)
{
case (a.__index b.__index): return 1;
default: return 0;
}
});
// second candidate computation
// ============================
for (var i=0, _i=_candidates.length; i 0.05)):
case (!(_candidates[i][‘__candidate_details_second’][‘_ratio__length__plain_text_to_total_plain_text’] > 0.05)):
// sort _candidates — the more points, the closer to position 0
// ================
_candidates.sort(function (a, b)
{
switch (true)
{
case (a.__points_second > b.__points_second): return -1;
case (a.__points_second < b.__points_second): return 1;
default: return 0;
}
});
// return
// ======
return _candidates;
};
$R.getContent__computeDetailsForCandidateSecond = function (_e, _main)
{
var _r = {};
// bad candidate
// =============
if (_e._is__bad) { return _r; }
// total text
// ==========
_r['_ratio__length__plain_text_to_total_plain_text'] = (_e._length__plain_text / _main._length__plain_text);
_r['_ratio__count__plain_words_to_total_plain_words'] = (_e._count__plain_words / _main._count__plain_words);
// hidden
// ======
if ($R.parsingOptions._elements_visible.indexOf(‘|’+_tag_name+’|’) > -1)
{
// included inline
// _node, _tag_name must be defined
// will return, if node is hidden
switch (true)
{
case (_node.offsetWidth > 0):
case (_node.offsetHeight > 0):
break;
default:
switch (true)
{
case (_node.offsetLeft > 0):
case (_node.offsetTop > 0):
break;
default:
// exclude inline DIVs — which, stupidly, don’t have a width/height
if ((_tag_name == ‘div’) && ((_node.style.display || $.css( _node, “display” )) == ‘inline’))
{ break; }
// above target
// ============
if (_custom_mode == ‘above-the-target’)
{
// is ignored?
if ($R.parsingOptions._elements_above_target_ignore.indexOf(‘|’+_tag_name+’|’) > -1)
{ $R.debugOutline(_node, ‘clean-before’, ‘above-target’); return; }
// is image?
if (_tag_name == ‘img’)
{
_explored = (_explored || $R.getContent__exploreNodeAndGetStuff(_node, true));
if (_explored._is__image_large); else
{ $R.debugOutline(_node, ‘clean-before’, ‘above-target’); return; }
}
// has too many links?
//if (_node.getElementsByTagName && _node.getElementsByTagName(‘a’).length > 5)
// { $R.debugOutline(_node, ‘clean-before’, ‘above-target’); return; }
}
// headers that are images
// =======================
if (_tag_name.match(/^h(1|2|3|4|5|6)$/gi))
{
_explored = (_explored || $R.getContent__exploreNodeAndGetStuff(_node, true));
switch (true)
{
case ((_explored._length__plain_text 0)):
$R.debugOutline(_node, ‘clean-before’, ‘skip-heading’);
return;
}
}
// start tag
// =========
if ($R.parsingOptions._elements_ignore_tag.indexOf(‘|’+_tag_name+’|’) > -1); else
{
/* mark */ _pos__start__before = _global__the_html.length;
/* add */ _global__the_html += ‘<'+_tag_name;
// attributes
// ==========
// allowed attributes
// ==================
if (_tag_name in $R.parsingOptions._elements_keep_attributes)
{
for (var i=0, _i=$R.parsingOptions._elements_keep_attributes[_tag_name].length; i ”)
{ _global__the_html += ‘ ‘+_attribute_name+’=”‘+(_attribute_value)+'”‘; }
}
}
// keep ID for all elements
// ========================
var _id_attribute = _node.getAttribute(‘id’);
if (_id_attribute > ”)
{ _global__the_html += ‘ id=”‘+_id_attribute+'”‘; }
// links target NEW
// ================
if (_tag_name == ‘a’)
{ _global__the_html += ‘ target=”_blank”‘; }
// close start
// ===========
if ($R.parsingOptions._elements_self_closing.indexOf(‘|’+_tag_name+’|’) > -1) { _global__the_html += ‘ />’; }
else { _global__the_html += ‘>’;}
/* mark */ _pos__start__after = _global__the_html.length;
}
// child nodes
// ===========
if ($R.parsingOptions._elements_self_closing.indexOf(‘|’+_tag_name+’|’) > -1); else
{
for (var i=0, _i=_node.childNodes.length; i -1)):
return;
case (($R.parsingOptions._elements_self_closing.indexOf(‘|’+_tag_name+’|’) > -1)):
/* mark */ _pos__end__before = _global__the_html.length;
/* mark */ _pos__end__after = _global__the_html.length;
break;
default:
/* mark */ _pos__end__before = _global__the_html.length;
/* end */ _global__the_html += ”;
/* mark */ _pos__end__after = _global__the_html.length;
break;
}
// clean — after
// =====
// we need to actually cut things out of
// “_global__the_html”, for stuff to not be there
// actually do it
_recursive(_nodeToBuildHTMLFor);
// return html
return _global__the_html;
};
// article title marker
// ====================
$R.articleTitleMarker__start = ‘
‘;
$R.articleTitleMarker__end = ‘
‘;
// article title check function
// ============================
$R.getContent__find__hasIsolatedTitleInHTML = function (_html)
{
return (_html.substr(0, $R.articleTitleMarker__start.length) == $R.articleTitleMarker__start);
};
// article title get function
// ============================
$R.getContent__find__getIsolatedTitleInHTML = function (_html)
{
// is it there?
if ($R.getContent__find__hasIsolatedTitleInHTML(_html)); else { return ”; }
// regex
var
_getTitleRegex = new RegExp($R.articleTitleMarker__start + ‘(.*?)’ + $R.articleTitleMarker__end, ‘i’),
_getTitleMatch = _html.match(_getTitleRegex)
;
// match?
if (_getTitleMatch); else { return ”; }
// return
return _getTitleMatch[1];
};
// find title in arbitrary html
// ============================
$R.getContent__find__isolateTitleInHTML = function (_html, _document_title)
{
// can’t just use (h1|h2|h3|etc) — we want to try them in a certain order
// =============================
var
_heading_pregs = [
/]*?>([sS]+?)/gi,
/]*?>([sS]+?)/gi,
/]*?>([sS]+?)/gi
],
_secondary_headings = ‘|h2|h3|h4|h5|h6|’,
_search_document_title = ‘ ‘ + _document_title.replace(/]+?>/gi, ”).replace(/s+/gi, ‘ ‘) + ‘ ‘
;
// loop pregs
// ==========
for (var i=0, _i=_heading_pregs.length; i -1)):
// will continue loop
break;
// return?
switch (true)
{
case (!(_heading_length > 5)):
case (!(_heading_length < (65 * 3))):
case (!(_to_heading_length -1)):
// words in this heading
_heading_words = _heading_text_plain.split(‘ ‘);
// count words present in title
for (var j=0, _j=_heading_words.length, _matched_words=”; j -1) {
_matched_words += _heading_words[j] + ‘ ‘;
}
}
// break continues for loop
// nothing goes to switch’s default
// ================================
// no break?
var _no_break = false;
switch (true)
{
// if it’s big enough, and it’s a substring of the title, it’s good
case ((_heading_length > 20) && (_search_document_title.indexOf(_heading_text_plain) > -1)):
// if it’s slightly smaler, but is exactly at the begging or the end
case ((_heading_length > 10) && ((_search_document_title.indexOf(_heading_text_plain) == 1) || (_search_document_title.indexOf(_heading_text_plain) == (_search_document_title.length – 1 – _heading_text_plain.length)))):
_no_break = true;
break;
}
// break?
var _break = false;
switch (true)
{
// no break?
case (_no_break):
break;
// heading too long? — if not h2
case ((_heading_length > ((_search_document_title.length – 2) * 2)) && (_heading_type != ‘h2’)):
// heading long enough?
case ((_heading_length < Math.ceil((_search_document_title.length – 2) * 0.50))):
// enough words matched?
case ((_heading_length < 25) && (_matched_words.length < Math.ceil(_heading_length * 0.75))):
case ((_heading_length < 50) && (_matched_words.length < Math.ceil(_heading_length * 0.65))):
case ((_matched_words.length ” ? $R.document.title : ”)
;
// get title
// =========
// has title already?
_foundHTML = $R.getContent__find__isolateTitleInHTML(_foundHTML, _documentTitle);
$R.articleTitle = $R.getContent__find__getIsolatedTitleInHTML(_foundHTML);
$R.debugPrint(‘TitleSource’, ‘target’);
// get html above?
if ($R.articleTitle > ”); else
{
// get html above target?
// ======================
// is what we found any good?
// ==========================
switch (true)
{
case ($R.getContent__find__hasIsolatedTitleInHTML(_aboveHTML)):
case (_differentTargets && (_aboveHTML.split(‘<a ').length < 3) && ($R.measureText__getTextLength(_aboveHTML.replace(/]+?>/gi, ”).replace(/s+/gi, ‘ ‘)) ”); else
{
// if all else failed, get document title
// ======================================
// loop through pregs
// ==================
for (var i=0, _i=_doc_title_pregs.length; i 1) { break; }
}
// sort title parts — longer goes higher up — i.e. towards 0
// ================
_doc_title_parts.sort(function (a, b)
{
switch (true)
{
case (a.length > b.length): return -1;
case (a.length 1 ? _doc_title_parts[0] : _documentTitle)
+ $R.articleTitleMarker__end
// debug
if ($R.debug)
{
// debug first candidates
$R.log(‘First 5 Main Candidates:’);
for (var x in _processedCandidates)
{
if (x == 5) { break; }
$R.log(_processedCandidates[x], _processedCandidates[x].__node);
}
// highlight first
$R.debugOutline(_firstCandidate.__node, ‘target’, ‘first’);
}
// in case we stop
$R.debugPrint(‘Target’, ‘first’);
// do second?
switch (true)
{
case (!(_firstCandidate._count__containers > 0)):
case (!(_firstCandidate._count__candidates > 0)):
case (!(_firstCandidate._count__pieces > 0)):
case (!(_firstCandidate._count__containers > 25)):
break;
default:
$R.debugTimerStart(‘ProcessSecond’);
var _processedCandidatesSecond = $R.getContent__processCandidatesSecond(_processedCandidates);
_secondCandidate = _processedCandidatesSecond[0];
$R.debugPrint(‘ProcessSecond’, $R.debugTimerEnd()+’ms’);
// they’re the same
if (_firstCandidate.__node == _secondCandidate.__node) { break; }
// debug
if ($R.debug)
{
// log second candidates
$R.log(‘First 5 Second Candidates:’);
for (var x in _processedCandidatesSecond)
{
if (x == 5) { break; }
$R.log(_processedCandidatesSecond[x], _processedCandidatesSecond[x].__node);
}
// highlight second
$R.debugOutline(_secondCandidate.__node, ‘target’, ‘second’);
}
var _caption2 = ”;
for (var i=0, _i=_caption.length, _code=0; i 127 ? (‘&#’+_code+’;’) : _caption.charAt(i));
}
_caption = _caption2;
switch (true)
{
case (!(_href > ”)):
case (_mainPageHref.length > _href.length):
case (_mainPageDomain != $R.getURLDomain(_href)):
case (_href.substr(_mainPageHref.length).substr(0, 1) == ‘#’):
case (_distance > Math.ceil(_distanceFactor * _path.length)):
return null;
default:
// skip if already loaded as next page
for (var i=0, _i=$R.nextPage__loadedPages.length; i<_i; i++)
{ if ($R.nextPage__loadedPages[i] == _href) { return null; } }
// sort — the less points, the closer to position 0
// ====
_links.sort(function (a, b)
{
switch (true)
{
case (a._distance b._distance): return 1;
default: return 0;
}
});
// return
return _links;
};
// load to frame
// =============
$R.getContent__nextPage__loadToFrame = function (_pageNr, _nextPageURL)
{
// do ajax
// =======
$.ajax
({
‘url’ : _nextPageURL,
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as 't' or ' '),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the object holding the key.
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, 't');
// text is '[nt"e",nt{ntt"pluribus": "unum"nt}n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(—current time—)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(d{4})-(d{2})-(d{2})T(d{2}):(d{2}):(d{2}(?:.d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] – 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
var cx = /[u0000u00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-uffff]/g,
escapable = /[\"x00-x1fx7f-x9fu00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'b': '\b',
't': '\t',
'n': '\n',
'f': '\f',
'r': '\r',
'"' : '\"',
'\': '\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[n' + gap +
partial.join(',n' + gap) + 'n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{n' + gap + partial.join(',n' + gap) + 'n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i // <![CDATA[
// HTML5 placeholder plugin version 1.01
// Copyright (c) 2010-The End of Time, Mike Taylor, http://miketaylr.com
// MIT Licensed: http://www.opensource.org/licenses/mit-license.php
//
// Enables cross-browser HTML5 placeholder for inputs, by first testing
// for a native implementation before building one.
//
//
// USAGE:
//$('input[placeholder]').placeholder();
//
(function($){
//feature detection
var hasPlaceholder = ‘placeholder’ in document.createElement(‘input’);
//sniffy sniff sniff — just to give extra left padding for the older
//graphics for type=email and type=url
var isOldOpera = $.browser.opera && $.browser.version < 10.5;
$.fn.placeholder = function(options) {
//merge in passed in options, if any
var options = $.extend({}, $.fn.placeholder.defaults, options),
//cache the original 'left' value, for use by Opera later
o_left = options.placeholderCSS.left;
//first test for native placeholder support before continuing
//feature detection inspired by ye olde jquery 1.4 hawtness, with paul irish
return (hasPlaceholder) ? this : this.each(function() {
//local vars
var $this = $(this),
inputVal = $.trim($this.val()),
inputWidth = $this.width(),
inputHeight = $this.height(),
//grab the inputs id for the , or make a new one from the Date
inputId = (this.id) ? this.id : ‘placeholder’ + (+new Date()),
placeholderText = options.placeholderText ? options.placeholderText : $this.attr(‘placeholder’),
placeholder = $(”+ placeholderText + ”);
//stuff in some calculated values into the placeholderCSS object
options.placeholderCSS[‘width’] = inputWidth;
options.placeholderCSS[‘height’] = inputHeight;
//hide placeholder on focus
$this.focus(function(){
if (!$.trim($this.val())){
$this.next().hide();
};
});
//show placeholder if the input is empty
$this.blur(function(){
if (!$.trim($this.val())){
$this.next().show();
};
});
});
};
//expose defaults
$.fn.placeholder.defaults = {
//you can pass in a custom wrapper
inputWrapper: ‘
‘,
placeholderText: null,
//more or less just emulating what webkit does here
//tweak to your hearts content
placeholderCSS: {
‘font’:’0.75em sans-serif’,
‘color’:’#bababa’,
‘position’: ‘absolute’,
‘left’:’5px’,
‘top’:’3px’,
‘overflow-x’: ‘hidden’
}
};
})(jQuery);
// ]]>// 0 ) {
Evernote.Logger.debug(“Found selection by win.getSelection()”);
hasSelection = true;
}
}
else if ( win.selection && typeof win.selection.createRange == ‘function’ ) {
sel = win.selection.createRange();
if ( win.selection.type == ‘Text’ && typeof sel.htmlText == ‘string’ && sel.htmlText.length > 0 ) {
Evernote.Logger.debug(“Found selection by win.selection”);
hasSelection = true;
}
}
else if ( doc.selection && (typeof doc.selection.createRange == ‘function’ || typeof doc.selection.createRange == ‘object’) ) {
sel = doc.selection.createRange();
if(doc.selection.type == “None”)
sel = undefined;
if ( (doc.selection.type == ‘Text’) && (typeof sel.htmlText == ‘string’) && (sel.htmlText.length > 0) ) {
Evernote.Logger.debug(“Found selection by doc.selection”);
hasSelection = true;
}
}
if ( sel && !hasSelection && deep ) {
var nestedDocs = Evernote.Utils.getNestedDocuments( doc );
for ( var i = 0; i 0 ) {
return framedSel;
}
}
}
}
//if do not find any selection in document, try to find selection in HTMLTextArea|Input.
//Get Selection object for TextArea, and set selection as a Range object
if(doc.activeElement)
Evernote.Logger.debug( “Check selection in INPUT TEXT area (input, textarea), for active element :” + doc.activeElement.nodeName );
var activeEl = doc.activeElement;
if ( activeEl && ( (window.HTMLInputElement && (activeEl instanceof window.HTMLInputElement && activeEl.type == “text”)) || ( window.HTMLTextAreaElement && (activeEl instanceof window.HTMLTextAreaElement)) ) ) {
if ( activeEl.selectionStart != activeEl.selectionEnd ) {
var range = doc.createRange();
var textNode = doc.createTextNode( activeEl.value );
return {
document : doc,
selection : sel
};
} catch(e) {
Evernote.Logger.error(“Failed to find selection on the page due to error ” + e);
//Do not throw exception here, it is better to not show error to user and allow to clip article or something else.
}
return {
document: doc,
selection: null
}
};
// ]]>// <![CDATA[
Evernote.JSSerializer = {
_selectionFinder : new Evernote.SelectionFinder(window.document),
serialize : function( element, fullPage ) {
try {
var start = new Date().getTime();
var root = element || document.body.parentNode || document.body;
var serializer = new Evernote.NodeSerializer( window, new Evernote.ClipFullStylingStrategy() );
var parser = new Evernote.DomParser( window, null );
parser.parse( root, fullPage ? true: false, serializer);
var end = new Date().getTime();
Evernote.Logger.debug( "Clip.clipFullPage(): clipped body in " + (end – start) + " milliseconds" );
var images = [];
var imageUrls = serializer.getImagesUrls();
var serializer = new Evernote.NodeSerializer( window, new Evernote.ClipFullStylingStrategy() );
var parser = new Evernote.DomParser(window, Evernote.Utils.fixIERangeObject(range));
parser.parse( ancestor, false, serializer );
var end = new Date().getTime();
Evernote.Logger.debug( "JSSerializer.serializeSelection(): clipped selection in " + (end – start) + " milliseconds" );
var images = [];
var imageUrls = serializer.getImagesUrls();
// We keep a record of what we're currently showing (at least in some cases) so that we can update it in case the
// state of the page changes (like if the user scrolls).
var currentlyShownRect = null;
var currentRectOffsetTop = 0;
var currentRectOffsetLeft = 0;
var currentlyStatic = false;
// Makes a rectangle bigger in all directions by the number of pixels specified (or smaller, if 'amount' is
// negative). Returns the new rectangle.
function expandRect(rect, amount) {
return {
top: (rect.top – amount),
left: (rect.left – amount),
bottom: (rect.bottom + amount),
right: (rect.right + amount),
width: (rect.width + (2 * amount)),
height: (rect.height + (2 * amount))
};
}
function scrollToRect(rect) {
var sLeft = document.documentElement.scrollLeft;
var sTop = document.documentElement.scrollTop;
var left = rect.left – (Evernote.Utils.innerWidth() / 2) + sLeft;
var top = rect.top – (Evernote.Utils.innerHeight() / 2) + sTop;
scroller.scrollTo( { x: left, y: top }, 120, 20 );
}
// DrawStroke is obsolete, it is now always "true".
function revealRect(rect, drawStroke, staticView) {
// Save this info.
currentlyShownRect = rect;
currentRectOffsetTop = Evernote.Utils.scrollTop();
currentRectOffsetLeft = Evernote.Utils.scrollLeft();
currentlyStatic = staticView;
// We expand the rectangle for two reasons.
// 1) we want to expand it by the width of the stroke, so that when we draw out outline, it doesn't overlap our
// content.
// 2) We want to leave a little extra room around the content for aesthetic reasons.
rect = expandRect(rect, 8);
var x = rect.left;
var y = rect.top;
var width = rect.width;
var height = rect.height;
function revealStaticRect(rect, drawStroke) {
revealRect(rect, drawStroke, true);
}
function outlineElement(element, scrollTo) {
// See notes in Preview.js for why we use this method instead of just calling element.getBoundingClientRect().
if (scrollTo) {
Evernote.Logger.debug(“ContentVeil:scrollIntoViewIfNeeded “);
element.scrollIntoView(true);
}
var rect = Evernote.contentPreviewer.computeDescendantBoundingBox(element);
Evernote.Logger.debug(“Calculated rect ” + rect);
if (rect) {
var mutableRect = {
top: rect.top,
bottom: rect.bottom,
left: rect.left,
right: rect.right,
width: rect.width,
height: rect.height
}
// We don’t want to adjust ourselves into odd positions if the page is scrolled.
var sLeft = Evernote.Utils.scrollLeft();
var sTop = Evernote.Utils.scrollTop();
revealRect(mutableRect, true);
Evernote.Logger.debug(“Hide elements embeded”);
hideElements(“embed”, element);
hideElements(“object”, element);
Evernote.Logger.debug(“Hide elements iframe”);
hideElements(“iframe”, element);
Evernote.Logger.debug(“Show it”);
show();
}
else {
Evernote.Logger.warn(“Couldn’t create rectangle from element: ” + element.toString());
}
}
function hideAllActiveObjects() {
hideElements(“embed”);
hideElements(“object”);
hideElements(“iframe”);
}
function hideElements (tagName, exceptInElement) {
var els = document.getElementsByTagName(tagName);
for (var i = 0; i < els.length; i++) {
els[i].enSavedVisibility = els[i].style.visibility;
els[i].style.visibility = "hidden";
}
}
function showElements (tagName, inElement) {
if (!inElement) {
inElement = document;
}
var els = inElement.getElementsByTagName(tagName);
for (var i = 0; i // div.comic > img”,
“aspicyperspective.com”: “div.entry-content”,
“thewirecutter.com”: “div#content”,
“katespade.com”: “div#pdpMain”,
“threadless.com”: “section.product_section”,
“yelp.com”: “div#bizBox”,
“flickr.com”: “div#photo”,
“instagr.am”: “div.stage > div.stage-inner”,
“stackoverflow.com”: “div#mainbar”,
“makeprojects.com”: “div#guideMain”,
“cookpad.com”: “div#main”,
“imgur.com”: “div.image”,
“smittenkitchen.com”: “div.entry”,
“allrecipes.com”: “div#content-wrapper”,
“qwantz.com”: “img.comic”,
“questionablecontent.net”: “img#strip”,
“cad-comic.com”: “div#content”
}
var useFoundImage = [
“xkcd.com”
]
// These are the items we’re trying to collect. This first block is trivial.
var containsImages = Boolean(document.getElementsByTagName(“img”).length > 0);
var documentWidth = document.width;
var documentHeight = document.height;
var url = document.location.href;
var documentLength = document.body.textContent ? document.body.textContent.length : 0;
// These take slightly more work and are initialized only when requested.
var article = null;
var articleBoundingClientRect = null;
var selection = false; // This is easy to get, but is always “false” at load time until the user selects something.
var selectionIsInFrame = false;
var documentIsFrameset = false;
var selectionFrameElement = null;
var recommendationText = null;
// Internal state variables to keep us duplicating work.
var hasCheckedArticle = false;
// Experimental recognition of ‘image’ pages (like photo sites and comics).
function findImage() {
var imgs = document.getElementsByTagName(“img”);
var biggest = null;
var biggestArea = 0;
for (var i = 0; i biggestArea) {
biggest = imgs[i];
biggestArea = area;
}
}
return biggest;
}
function getAncestors(node) {
var an = [];
while (node) {
an.unshift(node);
node = node.parentNode;
}
return an;
}
function getDeepestCommonNode(nodeList1, nodeList2) {
var current = null;
for (var i = 0; i < nodeList1.length; i++) {
if (nodeList1[i] === nodeList2[i]) {
current = nodeList1[i];
}
else {
break;
}
}
return current;
}
function getCommonAncestor(nodeList) {
if (!nodeList.length) return null;
if (nodeList.length == 1) return nodeList[0];
var lastList = getAncestors(nodeList[0]);
var node = null;
for (var i = 1; i img”);
if (candidate.length > 0) {
Evernote.Logger.debug(“Found article in a single image”);
article = candidate.get(0);
articleBoundingClientRect = Evernote.ElementExtension.getBoundingClientRect(article);
}
}
}
// If we still didn’t find an article, let’s see if maybe it’s in a frame. Cleary fails on frames so we try this
// check before we use our clearly info.
if (!article) {
if (document.body.nodeName.toLowerCase() == “frameset”) {
documentIsFrameset = true;
var frame = findBiggestFrame();
if (frame && frame.contentDocument && frame.contentDocument.documentElement) {
selectionFrameElement = frame;
article = frame.contentDocument.documentElement;
articleBoundingClientRect = Evernote.ElementExtension.getBoundingClientRect(article);
}
}
}
// If we didn’t use any of our special case handling, we’ll use whatever clearly found.
if (!article) {
Evernote.Logger.debug(“Use clearly find article”);
if (data && data._elements && data._elements.length) {
article = data._elements[0];
if (data._elements.length > 1) {
// This will include *all* clearly elements (and whatever else in in between them).
article = getCommonAncestor(data._elements);
// This includes *just the last (and therefore most important)* element from the clearly detection.
// article = data._elements[data._elements.length – 1];
}
// If clearly found nothing (because it failed), then use the body of the document.
if (!article) {
article = document.body;
}
hasCheckedArticle = true;
callback();
}
// This will try and determine the ‘default’ page article. It will only run once per page, but it’s specifically
// called only on demand as it can be expensive.
function findArticle(callback) {
function afterInject() {
// If we’d previously computed an article element, but it’s lost its parent or become invisible, then we’ll try
// and re-compute the article. This can happen if, for example the page dynamically udaptes itself (like showing
// the latest news article in a box that updates periodically). This doesn’t guarantee that we clip something
// sane if this happens, (if the page re-writes itself while a clip is taking place, the results are
// indeterminate), but it will make such things less likely.
if (article &&
(!article.parentNode || !article.getBoundingClientRect || Evernote.ElementExtension.getBoundingClientRect(article).width == 0)) {
article = null;
hasCheckedArticle = false;
}
Evernote.Logger.debug(“afterInject”);
if (!hasCheckedArticle) {
Evernote.Logger.debug(“no article”);
if (!window || !window.ClearlyComponent)
{
Evernote.Logger.warn(“Couldn’t find clearly!”);
clearlyCallback(null, callback);
}
else {
Evernote.Logger.debug(“Call clearly to select article”);
try {
window.ClearlyComponent.getContentElementAndHTML(window, function(data){clearlyCallback(data, callback)});
} catch(e) {
Evernote.Logger.error(“Failed to find article by clearly due to error ” + e);
clearlyCallback(null, callback);
}
}
}
// If the page is big enough, clearly is excruciatingly slow. We’ll jsut get the whole page.
// @TODO: Maybe clearly can get faster.
else if (document.body.innerHTML.length > (1024 * 1024)) {
Evernote.Logger.warn(“Page over 1mb, skipping article detection.”);
clearlyCallback(null, callback);
}
else {
Evernote.Logger.debug(“callback”);
callback();
}
}
afterInject();
}
function findBiggestFrame() {
var frames = document.getElementsByTagName(“frame”);
var candidate = null;
var candidateSize = 0;
for (var i = 0; i candidateSize) {
candidate = frames[i];
candidateSize = area;
}
}
}
return candidate;
}
function getHostname() {
var match = document.location.href.match(/^.*?://(www.)?(.*?)(/|$)/);
if (match) {
return match[2];
}
return null;
}
function getDefaultArticle(callback) {
Evernote.Logger.debug(“getDefaultArticle”);
findArticle(function(){callback(article)});
// Article already exists, so we’ll return it.
if (article) return article;
}
// Looks for selections in the current document and descendent (i)frames.
// Returns the *first* non-empty selection.
function getSelection() {
// First we check our main window and return a selection if that has one.
var selection = window.getSelection();
if (selection && selection.rangeCount && !selection.isCollapsed) {
return selection;
}
// Then we’ll try our frames and iframes.
var docs = [];
var iframes = document.getElementsByTagName(“iframe”);
for (var i = 0; i < iframes.length; i++) {
docs.push(iframes[i]);
}
var frames = document.getElementsByTagName("frame");
for (var i = 0; i < frames.length; i++) {
docs.push(frames[i]);
}
var urlBase = document.location.href.replace(/^(https?://.*?)/.*/i, "$1").toLowerCase();
for (var i = 0; i < docs.length; i++) {
// If frames/iframes fail a same origin policy check, then they'll through annoying errors, and we wont be able
// to access them anyway, so we attempt to skip anything that wont match.
if (docs[i].src && docs[i].src.toLowerCase().substr(0, urlBase.length) !== urlBase) {
continue;
}
var doc = docs[i].contentDocument;
if (doc) {
var frameSelection = doc.getSelection();
if (frameSelection && frameSelection.rangeCount && !frameSelection.isCollapsed) {
selectionIsInFrame = true;
selectionFrameElement = docs[i];
return frameSelection;
}
}
else {
Evernote.Logger.warn("iframe contained no Document object.");
}
}
// Didn't find anything.
return null;
}
function getText(node, soFar, maxLen) {
if (node.nodeType == Evernote.Node.TEXT_NODE) {
var trimmed = node.textContent.trim().replace(/s+/g, " ");
if (trimmed === " " || trimmed === "") return soFar;
return soFar + " " + trimmed;
}
var banned = [
"script",
"noscript"
];
if (node.nodeType == Evernote.Node.ELEMENT_NODE) {
if (Evernote.ArrayExtension.indexOf(banned, node.nodeName.toLowerCase()) == -1) {
for (var i = 0; i maxLen) {
return soFar;
}
}
}
}
return soFar;
}
function getRecommendationText() {
var text = “”;
var MAX_LEN = 5000;
var selection = getSelection();
if (selection) {
var df = selection.getRangeAt(0).cloneContents();
var div = document.createElement(“div”);
div.appendChild(df);
text = getText(div, “”, MAX_LEN);
}
else if (article) {
text = getText(article, “”, MAX_LEN);
}
else {
text = getText(document.body, “”, MAX_LEN);
}
text = document.title + ” ” + text;
return text;
}
// Note: you must call getSelection() first to populate this field!
function getSelectionFrame() {
return selectionFrameElement;
}
function checkClearly() {
var clearlyDoc = Evernote.ElementExtension.querySelector(“iframe#readable_iframe”);
if (clearlyDoc) clearlyDoc = clearlyDoc.contentDocument;
if (clearlyDoc) clearlyDoc = Evernote.ElementExtension.querySelector(“body#body div#box”, clearlyDoc);
if (clearlyDoc) {
article = clearlyDoc;
articleBoundingClientRect = Evernote.ElementExtension.getBoundingClientRect(article);
}
}
// @TODO: This is fairly incomplete.
function getFavIconUrl() {
var links = document.getElementsByTagName(“link”);
var i;
for (i = 0; i // <![CDATA[
Evernote.Scroller = function Scroller( tab ) {
this.initialize( tab );
};
Evernote.Scroller.prototype.scrollTo = function ( endPoint, time, resolution ) {
this.abort();
this.endPoint = endPoint;
this.step = 0;
this.calculatePath( time, resolution );
var self = this;
this.proc = setInterval( function () {
if ( !self.doScroll() ) {
self.abort();
}
},
resolution );
};
Evernote.Scroller.prototype.calculatePath = function ( time, resolution ) {
this.path = [];
var sx = this.initialPoint.x;
var sy = this.initialPoint.y;
var ex = this.endPoint.x;
var ey = this.endPoint.y;
var k = (Math.PI * resolution) / time;
for ( var i = -(Math.PI / 2); i // <![CDATA[
function ContentPreview() {
Evernote.Logger.debug("Start creating preview box");
var contentVeil = new ContentVeil();
Evernote.Logger.debug("End creating preview box");
// Stores a reference to the last element that we used as a preview.
var previewElement = null;
var article = null;
function buildPreviewLegend() {
Evernote.Logger.debug("buildPreviewLegend: start");
var legend = document.createElement("div");
legend.id = "evernotePreviewLegend";
legend.className = "evernotePreviewLegend";
if(Evernote.Utils.isQuirkMode() || Evernote.BrowserDetection.isLessThanIE9()) {
legend.className += " quirk-mode";
legend.className += " evernote-preview-position-top";
}
legend.dir = "ltr"; // It ends up backwards on right-to-left pages otherwise.
var nudgeImgs = [
// Element class name Message identifier
["icon-arrow-up", { message: Evernote.Messages.EXPAND_SELECTION, image: "images/nudge-icons/nudge-icon-arrow-up.png"} ],
["icon-arrow-down", { message: Evernote.Messages.SHRINK_SELECTION, image: "images/nudge-icons/nudge-icon-arrow-down.png"}],
["icon-arrow-lr", { message: Evernote.Messages.MOVE_SELECTION, image: "images/nudge-icons/nudge-icon-arrow-lr.png"}],
["icon-return", { message: Evernote.Messages.CLIP_ARTICLE_HINT, image: "images/nudge-icons/nudge-icon-return.png"}]
];
var ul = document.createElement("UL");
Evernote.Logger.debug("buildPreviewLegend: populate container");
for (var i = 0; i < nudgeImgs.length; i++) {
var li = document.createElement("li");
if(i == nudgeImgs.length – 1)
li.className = "last";
var div = document.createElement("div");
var message = document.createTextNode(Evernote.Addin.getLocalizedMessage(nudgeImgs[i][1].message));
div.className = "keyIcon " + nudgeImgs[i][0];
Evernote.GlobalUtils.absolutizeImages(div, nudgeImgs[i][1].image);
li.appendChild(div);
var messageContainer = document.createElement("span");
messageContainer.appendChild(message);
li.appendChild(messageContainer);
var clearDiv = document.createElement("div");
div.style.clear = "both";
li.appendChild(clearDiv);
ul.appendChild(li);
}
Evernote.Logger.debug("buildPreviewLegend: populate container end");
legend.appendChild(ul);
return legend;
}
function removePreviewLegend() {
if (Evernote.ElementExtension.hasParentNode(previewLegend)) {
previewLegend.parentNode.removeChild(previewLegend);
}
}
function buildUrlElement() {
var urlEl = document.createElement("div");
urlEl.id = "evernotePreviewContainer";
var className = "evernotePreviewContainer evernotePreviewUrlContainer";
if(Evernote.Utils.isQuirkMode()) {
className += " evernote-middle-fixed-position-quirks"
}
urlEl.className = className;
return urlEl;
}
Evernote.Logger.debug("Build url element");
var urlElement = buildUrlElement();
function showUrlElement() {
Evernote.Logger.debug("ContentPreview: showUrlElement start");
if (!Evernote.ElementExtension.hasParentNode(urlElement)) {
document.body.appendChild(urlElement);
}
// Make sure we're centered in the window.
var elStyle = Evernote.ElementExtension.getComputedStyle(urlElement, '');
var w = parseInt(Evernote.StyleElementExtension.getPropertyValue(elStyle, "width"));
var h = parseInt(Evernote.StyleElementExtension.getPropertyValue(elStyle, "height"));
if (w && h) {
urlElement.style.marginLeft = (0 – w / 2) + "px";
urlElement.style.marginTop = (0 – h / 2) + "px";
}
Evernote.Logger.debug("ContentPreview: showUrlElement end");
}
function hideUrlElement() {
if (Evernote.ElementExtension.hasParentNode(urlElement)) {
urlElement.parentNode.removeChild(urlElement);
}
}
function previewUrl() {
previewElement = null;
clear();
contentVeil.reset();
contentVeil.gray();
var title = window.document.title;
var url = PageContext.url;
var favIconUrl =PageContext.getFavIconUrl();
urlElement.innerHTML = Evernote.GlobalUtils.createUrlClipContent(title, url, favIconUrl);
showUrlElement();
contentVeil.hideAllActiveObjects();
}
// This doesn't remove internal state of previewElement, because another script may not have finished clipping until
// after the page looks 'clear'.
function clear() {
contentVeil.reset();
contentVeil.hide();
hideUrlElement();
removePreviewLegend();
}
function _previewArticle (showHelp) {
Evernote.Logger.debug("Start previewing article element");
if (previewElement)
{
var selectionFrame;
if (typeof Evernote.pageInfo !== undefined) {
selectionFrame = Evernote.pageInfo.getSelectionFrame();
}
Evernote.Logger.debug("Selection frame selected " + selectionFrame);
if (selectionFrame) {
var rect = {
width: selectionFrame.width,
height: selectionFrame.height,
top: selectionFrame.offsetTop,
bottom: (selectionFrame.height + selectionFrame.offsetTop),
left: selectionFrame.offsetLeft,
right: (selectionFrame.width + selectionFrame.offsetLeft)
};
Evernote.Logger.debug("contentVeil.revealStaticRect " + rect);
contentVeil.revealStaticRect(contentVeil.expandRect(rect, -9), true);
Evernote.Logger.debug("contentVeil.show ");
contentVeil.show();
}
else {
Evernote.Logger.debug("contentVeil.outlineElement");
contentVeil.outlineElement(previewElement, true);
}
if (showHelp) {
Evernote.Logger.debug("showPreviewLegend");
showPreviewLegend();
Evernote.Logger.debug("setTimeout:hidePreviewLegend");
setTimeout(hidePreviewLegend, 6000);
}
}
else {
Evernote.Logger.warn("Couldn't find a preview element. We should switch to 'full page' mode.");
}
}
/**
* Finds and preview article element.
* If reloadArticle is specified and equals to true, then discard previously found article and re-start search of article again.
* Otherwise use article found on previous call (if this is the first call then article will be searched anyway).
* @param reloadArticle
*/
function previewArticle (reloadArticle) {
var showHelp = Evernote.Options.articleSelection == Evernote.ArticleSelectionOptions.ENABLED;
// When nudging the preview around the page, we want to skip nodes that aren't interesting. This includes empty
// nodes, containers that have identical contents to the already selected node, invisible nodes, etc.
// @TODO: There's a lot more we could probably add here.
function looksInteresting(candidate, given) {
if (!candidate) {
Evernote.Logger.warn("Can't determine if 'null' is interesting (it's probably not).");
return false;
}
// This is the parent of our 'HTML' tag, but has no tag itself. There's no reason it's ever more interesting than
// the HTML element.
if (candidate === window.document) {
return false;
}
//Disable clip of evernote main popup
if(Evernote.JQuery(candidate).closest("#evernote-content").length != 0) {
return false;
}
// We don't want to clip the clipper controls notification.
// @TODO: Probably want something similar for the content veil.
if (candidate === previewLegend) {
return false;
}
// Elements with neither text nor images are not interesting.
if (!candidate.textContent && (candidate.getElementsByTagName("img").length === 0)) {
return false;
}
// Elements with 0 area are not interesting.
var rect = Evernote.ElementExtension.getBoundingClientRect(candidate);
if (!rect.width || !rect.height) {
return false;
}
// Invisible elements are not interesting.
var style = Evernote.ElementExtension.getComputedStyle(candidate);
if ((style.visibility === "hidden") || (style.display === "none")) {
return false;
}
// If the nodes have a parent/child relationship, then they're only interesting if their visible contents differ.
if (candidate.parentNode && given.parentNode) {
if ((candidate.parentNode == given) || (given.parentNode == candidate)) {
if ((candidate.textContent === given.textContent) &&
(candidate.getElementsByTagName("img").length === given.getElementsByTagName("img").length)) {
return false;
}
}
}
return true;
}
// Returns the current article element, which may not be the same as the auto-detected one if the user has 'nudged'
// the selection around the page.
function getArticleElement() {
return previewElement;
}
function nudgePreview(direction) {
Evernote.Logger.debug("nudgePreview start");
if (!previewElement) {
return;
}
var oldPreview = previewElement;
Evernote.Logger.debug("nudgePreview: direction is " + direction);
Evernote.Logger.debug("nudgePreview: previewElement is " + previewElement.nodeName);
switch (direction) {
case "up":
var temp = previewElement.parentNode;
while (temp) {
if (looksInteresting(temp, previewElement)) {
// If we move up and then down, we want to move back to where we started, not the first child.
temp.enNudgeDescendToNode = previewElement;
previewElement = temp;
break;
}
temp = temp.parentNode;
}
break;
case "down":
Evernote.Logger.debug("nudgePreview: previewElement.enNudgeDescendToNode is " + previewElement.enNudgeDescendToNode);
if (previewElement.enNudgeDescendToNode)
{
var temp = previewElement.enNudgeDescendToNode;
// @TODO: make sure we clean these up somewhere else if we never reverse our nudging.
try {
delete previewElement.enNudgeDescendToNode;
} catch(e) {
previewElement.enNudgeDescendToNode = undefined;
}
previewElement = temp;
break;
}
Evernote.Logger.debug("nudgePreview: previewElement.children.length = " + previewElement.children.length);
for (var i = 0; i < previewElement.children.length; i++) {
Evernote.Logger.debug("nudgePreview: checking child is " + previewElement.children[i].nodeName);
if (looksInteresting(previewElement.children[i], previewElement)) {
Evernote.Logger.debug("nudgePreview: found interesting child" + previewElement.children[i]);
previewElement = previewElement.children[i];
break;
}
}
break;
case "left":
var temp = previewElement.previousElementSibling;
while (temp) {
if (looksInteresting(temp, previewElement)) {
previewElement = temp;
break;
}
temp = temp.previousElementSibling;
}
break;
case "right":
var temp = previewElement.nextElementSibling;
while (temp) {
if (looksInteresting(temp, previewElement)) {
previewElement = temp;
break;
}
temp = temp.nextElementSibling;
}
break;
default:
Evernote.Logger.warn("Unhandled nudge direction: " + direction);
}
// Drawing is expensive so don't bother if nothing changed.
if (oldPreview !== previewElement) {
Evernote.Logger.debug("nudgePreview: draw new element.");
contentVeil.outlineElement(previewElement, true);
}
}
function previewFullPage() {
var borderWidth = 10;
var w = Evernote.Utils.innerWidth();
var h = Evernote.Utils.innerHeight();
var rect = {
bottom: (h – borderWidth),
top: (borderWidth),
left: (borderWidth),
right: (w – borderWidth),
width: (w – (2 * borderWidth)),
height: (h – (2 * borderWidth))
}
// Creates the union of two rectangles, which is defined to be the smallest rectangle that contains both given
// rectangles.
function unionRectangles(rect1, rect2) {
var rect = {
top: (Math.min(rect1.top, rect2.top)),
bottom: (Math.max(rect1.bottom, rect2.bottom)),
left: (Math.min(rect1.left, rect2.left)),
right: (Math.max(rect1.right, rect2.right))
}
rect.width = rect.right – rect.left;
rect.height = rect.bottom – rect.top;
return rect;
}
// Returns true if the rectangles match, false otherwise.
function rectanglesEqual(rect1, rect2) {
if (!rect1 && !rect2) return true;
if (!rect1) return false;
if (!rect2) return false;
if (rect1.top != rect2.top) return false;
if (rect1.bottom != rect2.bottom) return false;
if (rect1.left != rect2.left) return false;
if (rect1.right != rect2.right) return false;
if (rect1.width != rect2.width) return false;
if (rect1.height != rect2.height) return false;
return true;
}
// If the user triple-clicks a paragraph, we will often get a selection that includes the next paragraph after the
// selected one, but only up to offset 0 in that paragraph. This causes the built in getBoundingClientRect to give a
// box that includes the whole trailing paragraph, even though none of it is actually selected. Instead, we'll build
// our own bounding rectangle that omits the trailing box.
// @TODO: Currently this computes a box that is *too big* if you pass it a range that doesn't have start and/or end
// offsets that are 0, because it will select the entire beginning and ending node, instead of jsut the selected
// portion.
function computeAlternateBoundingBox(range) {
// If the end of selection isn't at offset 0 into an element node (rather than a text node), then we just return the
// original matching rectangle.
if ((range.endOffset !== 0) ||
(range.endContainer.nodeType !== Evernote.Node.ELEMENT_NODE) ||
( range.startContainer && range.startContainer.getBoundingClientRect) ||
( range.endContainer && range.endContainer.getBoundingClientRect) ||
( range.commonAncestorContainer && range.commonAncestorContainer.getBoundingClientRect)
) {
var rect = Evernote.ElementExtension.getBoundingClientRect(range);
if(rect.top == 0 && rect.bottom == 0 && rect.left == 0 && rect.right == 0) {
if(range.commonAncestorContainer && range.commonAncestorContainer.getBoundingClientRect) {
rect = range.commonAncestorContainer.getBoundingClientRect();
} else if(range.startContainer && range.startContainer.getBoundingClientRect) {
rect = range.startContainer.getBoundingClientRect();
} else if(range.endContainer && range.endContainer.getBoundingClientRect) {
rect = range.endContainer.getBoundingClientRect();
}
}
var mutableRect = {
top: rect.top,
bottom: rect.bottom,
left: rect.left,
right: rect.right,
width: rect.width,
height: rect.height
};
return mutableRect;
}
// This is the one we don't want.
var endElementRect = null;
try {
endElementRect = Evernote.ElementExtension.getBoundingClientRect(range.endContainer);
}
catch(ex) {
Evernote.Logger.warn("Couldn't get a bounding client rect for our end element, maybe it's a text node.");
}
// We look for a rectangle matching our end element, and if we find it, we don't copy it to our list to keep.
// You'd think we could just grab the last element in range.getClientRects() here and trim that one, which might be
// true, but the spec makes no claim that these are returned in order, so I don't want to rely on that.
// We keep track if we remove a rectangle, as we're only trying to remove one for the trailnig element. If there are
// more than one matching rectangle, we want to keep all but one of them.
var foundEnd = false;
var keptRects = [];
var initialRects = range.getClientRects();
for (var i = 0; i < initialRects.length; i++) {
if (rectanglesEqual(endElementRect, initialRects[i]) && !foundEnd) {
foundEnd = true;
}
else {
keptRects.push(initialRects[i]);
}
}
// Now compute our new bounding box and return that.
if (keptRects.length == 0) return Evernote.ElementExtension.getBoundingClientRect(range);
if (keptRects.length == 1) return keptRects[0];
var rect = keptRects[0];
for (var i = 1; i 1) {
newRect = unionRectangles(Evernote.ElementExtension.getBoundingClientRect(element), rect);
}
if (element.children) {
for (var i = 0; i < element.children.length; i++) {
newRect = applyElementRect(element.children[i], newRect);
}
}
return newRect;
}
// In the case of positioned elements, a bounding box around an element doesn't necessarily contain its child
// elements, so we have this method to combine all of these into one bigger box. ContentVeil calls this function.
function computeDescendantBoundingBox(element) {
if (!element) return {top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0};
return applyElementRect(element, Evernote.ElementExtension.getBoundingClientRect(element));
}
function previewSelection(sel) {
var selection;
var selectionFrame;
if(sel) {
selection = sel;
}
else if (typeof Evernote.pageInfo !== undefined) {
selection = Evernote.pageInfo.getSelection();
// If our selection is in a frame or iframe, we'll compute an offset relative to that, so we need to adjust it by
// the offset of the frame.
selectionFrame = Evernote.pageInfo.getSelectionFrame();
}
contentVeil.reset();
var frameRect = null;
if (selectionFrame) {
frameRect = Evernote.ElementExtension.getBoundingClientRect(selectionFrame);
}
var range, rect, i;
// If !selection, then something has gone awry.
if (selection) {
clear();
contentVeil.reset();
// We attempt to highlight each selection, but this hasn't been tested for more than a single selection.
for (i = 0; i // // <![CDATA[
Evernote.ArrayExtension = {
indexOf : function(element, searchStr) {
if (element.indexOf)
return element.indexOf(searchStr);
for(var i = 0; i >> 0;
if (typeof fun != “function”)
throw new TypeError();
var res = [];
var thisp = arguments[1];
for (var i = 0; i // <![CDATA[
Evernote.StyleElementExtension = {
getPropertyValue : function(styleObj, propertyName) {
var props = propertyName;
if(!(props instanceof Array)) {
props = [propertyName];
}
Evernote.Logger.debug("Evernote.StyleElementExtension.getPropertyValue: number of properties to check " + props.length);
for(var i = 0; i // <![CDATA[
Evernote.GlobalUtils = {};
(function(){
var urlMatcher = /^(.*?)://((www.)?(.*?))(:d+)?(/.*?)(?.*)?$/;
Evernote.GlobalUtils.absolutizeImages = function(element, path) {
if(path) {
Evernote.Utils.changeBackgroundImage(element, Evernote.Addin.getPath("resources") + path);
}
else if(element.attributes && element.attributes["background-image"]) {
Evernote.Utils.changeBackgroundImage(element, Evernote.Addin.getPath("resources") + element.attributes["background-image"].value);
}
Evernote.Logger.debug("absolutizeImages: walk through children");
for (var i = 0; i < element.children.length; i++) {
Evernote.GlobalUtils.absolutizeImages(element.children[i]);
}
Evernote.Logger.debug("absolutizeImages: end");
};
Evernote.GlobalUtils.localize = function(element) {
Evernote.Logger.debug("localize: Before lowercase");
Evernote.Logger.debug("localize: element " + element);
Evernote.Logger.debug("localize: element.nodeName " + element.nodeName);
var node = element.nodeName.toLowerCase();
Evernote.Logger.debug("localize: after lowercase");
if (node == "input" || node == "textarea") {
var type = element.type;
if (node == "textarea") type = "textarea";
switch (element.type) {
case "text":
case "textarea":
case "button":
case "submit":
case "search":
if (element.attributes && element.attributes["placeholder"]) {
var localizedMessage = Evernote.Addin.getLocalizedMessage(Evernote.GlobalUtils.getMessageCode(element.attributes["placeholder"].value));
Evernote.Logger.debug("localizedMessage is " + localizedMessage);
if (localizedMessage) {
try {
element.attributes["placeholder"].value = localizedMessage;
} catch(e) {
var placeHolderAttr = document.createAttribute("placeholder");
placeHolderAttr.nodeValue = localizedMessage;
element.setAttribute("placeholder", localizedMessage);
}
}
}
if (element.attributes && element.attributes["message"]) {
var localizedMessage = Evernote.Addin.getLocalizedMessage(Evernote.GlobalUtils.getMessageCode(element.attributes["message"].value));
Evernote.Logger.debug("localizedMessage is " + localizedMessage);
if (localizedMessage) {
element.value = localizedMessage;
}
}
break;
// unlocalizable.
case "checkbox":
case "password":
case "hidden":
break;
default:
throw new Error("We need to localize the value of input elements.");
}
}
else if (element.attributes && element.attributes["message"]) {
var localizedMessage = Evernote.Addin.getLocalizedMessage(Evernote.GlobalUtils.getMessageCode(element.attributes["message"].value));
if (localizedMessage) {
element.innerHTML = localizedMessage;
}
}
if (element.title){
var localizedTitle = Evernote.Addin.getLocalizedMessage(Evernote.GlobalUtils.getMessageCode(element.title));
if (localizedTitle) {
element.title = localizedTitle;
}
}
for (var i = 0; i < element.children.length; i++) {
Evernote.GlobalUtils.localize(element.children[i]);
}
};
Evernote.GlobalUtils.getQueryParams = function(url) {
var data = Evernote.GlobalUtils.componentizeUrl(url);
var queryString = data.queryString;
var params = {};
if (!queryString) {
return params;
};
queryString = queryString.substr(1); // Don't want the question mark.
queryString = queryString.split("#")[0]; // Get rid of any fragment identifier.
var pairs = queryString.split("&");
var i;
for (i = 0; i < pairs.length; i++) {
var item = pairs[i].split("=");
if (item[1]) {
item[1] = item[1].replace(/+/g, " ");
}
params[item[0].toLowerCase()] = item[1];
}
return params;
};
/**
* Make selection of passed range in document.
* @param doc – DOM object
* @param range – selection range
*/
selectRange : function(doc, range) {
if(doc.getSelection) {
doc.getSelection().addRange(range);
}
else if (doc.selection && range) {
range.select();
}
},
/**
* Creates copy of selection range only if it supports it, otherwise returns same range
* @param range – Range object
* @return {Range}
*/
cloneRange : function(range) {
Evernote.Logger.debug("cloneRange: start");
if(range && range.cloneRange) {
return range.cloneRange();
}
if(range.duplicate) {
Evernote.Logger.debug("cloneRange: result = " + range.duplicate());
return range.duplicate();
}
return range;
},
/**
* Checks whether selection is presented.
* @param win – window object that should be checked.
* @return true – if selection is presented, false otherwise.
*/
hasSelection : function(win) {
Evernote.Logger.debug( "Utils.hasSelection()" );
var selectionFinder = new Evernote.SelectionFinder(win.document)
if ( selectionFinder.hasSelection() ) {
return true;
}
else {
selectionFinder.find( true );
return selectionFinder.hasSelection();
}
},
/**
* Gets favicon url from the document (if any)
* @param doc – document to inspect.
* @return url to the favicon or null.
*/
getFavIconUrl : function(doc) {
var links = doc.getElementsByTagName("link");
var i;
for (i = 0; i length) {
return (str.substring(0, length-3) + “…”);
}
return str;
},
/**
* Change new line symbol to html
*/
newLineToBr : function(str) {
return str.replace(/(rn|n|r)/gm, ”
“);
},
/**
* Encodes html specific characters (, &, etc.) in specified string
* @param str – string to encode.
* @return new string with encoded characters.
*/
htmlEncode : function( str ) {
var result = “”;
for ( var i = 0; i = 55296 )
result += aChar;
else if ( charcode > 0x7f ) {
result += “&#” + charcode + “;”;
}
else if ( aChar == ‘>’ ) {
result += “>”;
}
else if ( aChar == ‘<' ) {
result += "<";
}
else if ( aChar == '&' ) {
result += "&";
}
else {
result += str[ i ] ? str[ i ] : str.charAt(i);
}
}
format: function(str) {
var args = arguments;
return str.replace(/{(d+)}/g, function (m, n) { return args[(n | 0)+1]; });
},
fixIERangeObject : function(range,win) { //Only for IE8 and below.
win=win || window;
if(!range) return null;
if(!range.startContainer && win.document.selection) { //IE8 and below
var _findTextNode=function(parentElement,text) {
//Iterate through all the child text nodes and check for matches
//As we go through each text node keep removing the text value (substring) from the beginning of the text variable.
var container=null,offset=-1;
for(var node=parentElement.firstChild; node; node=node.nextSibling) {
if(node.nodeType==3) {//Text node
var find=node.nodeValue;
var pos=text.indexOf(find);
if(pos==0 && text!=find) { //text==find is a special case
text=text.substring(find.length);
} else {
container=node;
offset=text.length-1; //Offset to the last character of text. text[text.length-1] will give the last character.
break;
}
}
}
//Debug Message
//alert(container.nodeValue);
return {node: container,offset: offset}; //nodeInfo
};
var rangeCopy1=range.duplicate(), rangeCopy2=range.duplicate(); //Create a copy
var rangeObj1=range.duplicate(), rangeObj2=range.duplicate(); //More copies :P
rangeCopy1.collapse(true); //Go to beginning of the selection
rangeCopy1.moveEnd(‘character’,1); //Select only the first character
rangeCopy2.collapse(false); //Go to the end of the selection
rangeCopy2.moveStart(‘character’,-1); //Select only the last character
//Debug Message
// alert(rangeCopy1.text); //Should be the first character of the selection
var parentElement1=rangeCopy1.parentElement(), parentElement2=rangeCopy2.parentElement();
//If user clicks the input button without selecting text, then moveToElementText throws an error.
if(window.HTMLInputElement && (parentElement1 instanceof window.HTMLInputElement || parentElement2 instanceof HTMLInputElement)) {
return null;
}
rangeObj1.moveToElementText(parentElement1); //Select all text of parentElement
rangeObj1.setEndPoint(‘EndToEnd’,rangeCopy1); //Set end point to the first character of the ‘real’ selection
rangeObj2.moveToElementText(parentElement2);
rangeObj2.setEndPoint(‘EndToEnd’,rangeCopy2); //Set end point to the last character of the ‘real’ selection
var text1=rangeObj1.text; //Now we get all text from parentElement’s first character upto the real selection’s first character
var text2=rangeObj2.text; //Here we get all text from parentElement’s first character upto the real selection’s last character
var nodeInfo1=_findTextNode(parentElement1,text1);
var nodeInfo2=_findTextNode(parentElement2,text2);
//Finally we are here
range.startContainer=nodeInfo1.node;
range.startOffset=nodeInfo1.offset;
range.endContainer=nodeInfo2.node;
range.endOffset=nodeInfo2.offset+1; //End offset comes 1 position after the last character of selection.
}
return range;
},
Evernote.ClipRules.SELF_CLOSING_NODES = {
“IMG” : null,
//”INPUT” : null,
“BR” : null
};
// ]]>// <![CDATA[
/**
* ClipStyle is a container for CSS styles. It is able to add and remove
* CSSStyleRules (and parse CSSRuleList's for rules), as well as
* CSSStyleDeclaration's and instances of itself.
* ClipStyle provides a mechanism to serialize itself via toString(), and
* reports its length via length property. It also provides a method to clone
* itself and expects to be manipulated via addStyle and removeStyle.
*/
Evernote.ClipStyle = function ClipStyle( css, filterFn, styleList ) {
this.initialize( css, filterFn, styleList );
};
Evernote.ClipStyle.CSS_GROUP.getExtForStyle = function ( name ) {
var list = this[ name ];
var extList = [ ];
if ( list ) {
for ( var i = 0; i = 0 ) {
var tmp = list[ i ];
extList.push( tmp.replace( “+”, “” ) );
}
else {
extList.push( name + “-” + list[ i ] );
}
}
return extList;
}
Evernote.ClipStyle.prototype.toString = function () {
var str = "";
var stylesNames = this.getStylesNames();
for ( var i = 0; i 0 ) {
str += styleName + “:” + value + “;”;
}
}
return "“;
}
catch ( e ) {
Evernote.Logger.error( “VideoElementSerializer.serialize() failed: error = ” + e );
}
return “”;
};
// ]]>// <![CDATA[
/**
* Serializes DOM element into an img pointing to the thumbnail of the video
*
* Video ids are used for obtaining thumbnails via
* https://i2.ytimg.com/vi/cAcxHQalWOw/hqdefault.jpg. These ids can be
* obtained from:
*
*
* - the URL of the document containing EMBED
* - iframe's src attribute that embeds the video via an iframe
* - src attribute of the embed object (though on actualy youtube.com it's not possible)
*
if ( node && node.nodeType == Evernote.Node.ELEMENT_NODE ) {
if ( Evernote.ArrayExtension.indexOf(this.VIDEO_NODES, node.nodeName.toUpperCase() ) >= 0 ) {
return node;
}
else if ( Evernote.ArrayExtension.indexOf(this.POSSIBLE_CONTAINER_NODES, node.nodeName.toUpperCase() ) >= 0 ) {
try {
var it = node.ownerDocument.createNodeIterator( node, NodeFilter.SHOW_ELEMENT, null, false );
var next = null;
while ( next = it.nextNode() ) {
if ( Evernote.ArrayExtension.indexOf(this.VIDEO_NODES, next.nodeName.toUpperCase() ) >= 0 ) {
return next;
}
}
} catch(e) {
//We ignore exception here, because if node iterator is not supported, than we could skip old pages (not Youtube).
return null;
}
}
}
if ( thumbUrl ) {
var styleStr = (this._nodeStyle instanceof Evernote.ClipStyle) ? ("style="" + this._nodeStyle.toString() + """) : "";
var attrs = this._node.attributes;
var attrStr = "";
for ( var i = 0; i this.constructor.DEFAULT_THUMB_WIDTH / this.constructor.DEFAULT_THUMB_HEIGHT ) {
imgAttrStr += “height=”” + h + “””;
}
else { // scale by width
imgAttrStr += “width=”” + w + “””;
}
}
getValue: function(val) {
if(typeof val != "string")
return val;
if(this.isCalculationRequired(val)) {
Evernote.Logger.error("Calculation required for val " + val);
return Evernote.Utils.getFontSizeInPixels(val) + "px";
} else {
//Do not set browser dependant CSS since it does not supported by Evernote Chromium Viewer.
return null;
}
},
isCalculationRequired: function(val) {
for(var i = 0; i // //
Introducing the “Exchange Server 2010 Technical Video Series” on TechCenter
Struggling to find an overview of what the latest EAS features are? Planning your migration from Exchange 2003 and looking for a basic introduction to Database Availability Groups (DAGs)? These videos are for you! The Microsoft Exchange team has produced a new portfolio of videos designed to give customers…
2536700 (http://support.microsoft.com/kb/2536700/ ) Outlook stops responding when you try to copy a folder to its subfolder by using Outlook in online mode in an Exchange Server 2010 SP1 environment
2536494 (http://support.microsoft.com/kb/2536494/ ) It takes a long time to return results when you perform an Advanced Find search on a mailbox by using Outlook in online mode in an Exchange Server 2010 SP1 environment
2533538 (http://support.microsoft.com/kb/2533538/ ) You cannot look up the free/busy information of a user who is located on an Exchange Server 2010 organization from another Exchange Server 2010 organization
2533451 (http://support.microsoft.com/kb/2533451/ ) A RBAC role assignee can unexpectedly run the “Update-FileDistributionService” command on an Exchange Server 2010 server that is outside the role assignment scope
2519359 (http://support.microsoft.com/kb/2519359/ ) “Changes to the rule cannot be saved.” error message when you try to create a reply rule by using Outlook in an Exchange Server 2010 environment
2513723 (http://support.microsoft.com/kb/2513723/ ) The “New-MailboxImportRequest” cmdlet does not import all messages in a .pst file in the ANSI format in an Exchange Server 2010 environment
2512023 (http://support.microsoft.com/kb/2512023/ ) “GetUserOofSettings”, “SetUserOofSettings” and “GetUserAvailability” operations do not support Exchange Impersonation on the Exchange Server 2010 SP1 schema
2511897 (http://support.microsoft.com/kb/2511897/ ) You cannot send an email message to a mailbox for a brief period when you move the mailbox by using online move in an Exchange Server 2010 environment
2504453 (http://support.microsoft.com/kb/2504453/ ) You cannot retrieve statistical information about a public folder by using the “Get-PublicFolderStatistics” cmdlet in an Exchange Server 2010 SP1 environment
2501070 (http://support.microsoft.com/kb/2501070/ ) A RBAC role assignee can stop queue processing on an Exchange Server 2010 Hub Transport server or an Exchange Server 2010 Edge Transport server that is outside the role assignment scope
2500648 (http://support.microsoft.com/kb/2500648/ ) “There are no items to show in this view.” error message when you try to view a folder in Outlook in an Exchange Server 2010 environment
2495010 (http://support.microsoft.com/kb/2495010/ ) The EdgeTransport.exe process consumes 100% CPU usage on an Exchange Server 2010 Edge Transport server or an Exchange Server 2007 Edge Transport server
2492068 (http://support.microsoft.com/kb/2492068/ ) “The item cannot be saved to this folder.” error message when try to post an item to a mail-disabled public folder in an Exchange Server 2010 SP1 environment
2489130 (http://support.microsoft.com/kb/2489130/ ) A RBAC role assignee can unexpectedly change mailbox properties that are outside the management role group scope in an Exchange Server 2010 environment
2479188 (http://support.microsoft.com/kb/2479188/ ) The iCal parts of an email message contain invalid entries when they are sent from an Exchange Server 2003 mailbox to an Exchange Server 2010 mailbox
2477273 (http://support.microsoft.com/kb/2477273/ ) The DomainController parameter does not work when you use the “MoveMailbox.ps1” script to move mailboxes in an Exchange Server 2010 environment
2471964 (http://support.microsoft.com/kb/2471964/ ) A NDR is sent to the sender when you move an email message to a personal folder file in an Exchange Server 2010 SP1 or a later version environment
2394554 (http://support.microsoft.com/kb/2394554/ ) An email message is not delivered if it contains unsupported encoded characters in the subject line in an Exchange Server 2010 environment
2549046 Description of cumulative update for Office Communications Server 2007 R2: June, 2011
2544768 An update is available that increases the maximum number of allowed access proxies in an access proxy array in Office Communications Server 2007 R2
June 3, 2011
924284 How to enable the Memory Diagnostic test for 2007 Office products on a Windows Server-based computer
Microsoft Exchange Online Standard
Microsoft® Exchange Online is a hosted enterprise messaging solution based on Microsoft Exchange Server 2007. Exchange Online services include advanced e-mail features as well as calendaring, contact, and task management capabilities. This…
Microsoft Forefront Endpoint Protection (FEP) 2010 Update Rollup 1 Tools
These free downloads make it easier for Forefront Endpoint Protection 2010 Update Rollup 1 customers to use Group Policy for centralized management, provide optimized settings for various server roles, and diagnose and troubleshoot support issues.
Microsoft Online Standard Service Descriptions
Microsoft Online Services provides enterprise-level hosted solutions for e-mail, collaboration, instant messaging and Web conferencing. Services are delivered from a highly reliable network of Microsoft data centers located strategically throughout the world that provides seamless connectivity to the Microsoft Online suite of services —enabling customers to use the latest productivity applications
Visio 2010 Add-in for Exchange Server 2007
This Microsoft Visio Add-In makes it easy for Exchange administrators to visualize, explore, and communicate complex…dramatically increase productivity. You can diagram a Microsoft® Exchange Server 2007 site topology, including sites, servers…
VHD Test Drive – Lync Server 2010 VHD
This download comes as a pre-configured set of VHD’s. This download enables you to fully evaluate Microsoft Lync Server 2010.
Microsoft Active Directory Topology Diagrammer
The Microsoft Active Directory Topology Diagrammer reads an Active Directory configuration using LDAP, and then automatically generates a Visio diagram of your Active Directory and /or your Exchange Server topology. The diagramms may include domains, sites, servers, organizational units, DFS-R, administrative groups, routing groups and connectors and can be changed manually in Visio if needed.
Live Meeting-To-Lync Transition Resources
Resources included in this download package are designed to support your organization’s Live Meeting Service to Lync (Server or Online) transition planning. This download will be updated with additional resources as available.
Tabbed Conversations for Microsoft Lync 2010
Tabbed Conversations is an application that provides a tabbed Lync 2010 conversation window to allow multiple instant messaging (IM) conversations in a single window.
Conversations Analyzer for Microsoft Lync 2010
Conversations Analyzer is an application that reviews your Microsoft Lync instant messaging (IM) conversation history and gives you scores for your use of trust-building language in day-to-day…
Conversation Translator Add-In for Microsoft Lync 2010
Conversation Translator provides a real-time language translation service for Lync instant messaging (IM) conversations. With Conversation Translator, both the sender and receiver can converse in their native language, and Conversation Translator handles the translation.
Information Dashboard Add-In for Microsoft Lync 2010
Information Dashboard helps you start a conversation with a remote contact by providing current information about the contact’s location. For example, if you are calling a co-worker or a client in Shanghai, China, you can open Information Dashboard and enter the location of Shanghai before making the call.
Microsoft Lync Server 2010 Group Chat Stress Tool
Group Chat Stress is a tool that can be used to help verify your Microsoft Lync Server 2010 and Microsoft Lync Server 2010, Group Chat hardware deployment. The Group Chat Stress package is made up of two applications…
Security in Office365 White Paper
This whitepaper provides an overview of the security practices and technology that support enterprise-grade security in Microsoft Office365 for businesses of all sizes.
HTML content in email messages for BlackBerry smartphones For BlackBerry® Device Software 4.5 to 6.0, HTML formatted content is supported on the BlackBerry® smartphone if the email account is integrated with the BlackBerry® Internet Service…
How to retrieve extended information for an SNMP service When creating a custom SNMP monitoring tool, OID is required. The OID is a numeric value with the following format . 1.3.6.1.4.1.3530.6.7.10.10.15.1.2 and it represents the item which…
BlackBerry Collaboration Service starts and stops The BlackBerry® Collaboration Service starts and stops within approximately 30 seconds. The following log lines appear in the BBIM debug log: : : : : : : : : : : : : : · BlackBerry®…
How to import IT policy rule definitions for PlayBook The attached file below contains several new IT Policies to support the BlackBerry® PlayBook™. Descriptions of these policies are below: Enable BlackBerry Bridge This policy can be found…
ID: KB26294 | Published: 5/24/11 |
Unable to view filed email messages The BlackBerry® smartphone user cannot view email messages that have been filed in a folder on the BlackBerry smartphone user’s mailbox on the messaging server. · BlackBerry® Enterprise Server for…
How to locate the BlackBerry Resource Kit log files This knowledge base article is intended to assist BlackBerry® Enterprise Server administrators with locating the logs generated when th BlackBerry Enterprise Transporter 4.1 to 5.0 64-bit…
” appears on Windows Event logs and BlackBerry MDS Connection Service logs after upgrading to BlackBerry Enterprise Server 5.0 SP2 and SP3 After upgrading to BlackBerry® Enterprise…ID: KB25239 | Published: 5/18/11 |
How to troubleshoot SRP connectivity issues Complete the following tasks to troubleshoot Server Routing Protocol (SRP) connectivity issues: 1. Run the BlackBerry Enterprise Server BBSRPTest.exe tool. 2. Locate the Network Access…
Supported configuration for HTTPS SSL/TLS encryption is supported over Hypertext Transfer Protocol (HTTP) on the BlackBerry® Enterprise Server and BlackBerry® smartphones. Depending on the configurations and installation of your…
Unable to remove the BlackBerry MDS Integration Service The process of removing the BlackBerry® Mobile Data System Integration Service from the BlackBerry® Domain consists of two steps: 1) Removing the BlackBerry MDS Integration Service…
How to locate the SRP ID and SRP Authentication Key The Server Routing Protocol Identifier (SRP ID) and SRP Authentication Key can be found in the following locations: · In the BlackBerry® Configuration Database · In the cached property…
Unable to open a document within the BlackBerry Browser When browsing to a URL ending with a file extension indicating a document of some type (such as .doc, .rtf, anything non .html – e.g h ttp://www.blackbe rry.com/blackberry.rtf) the file…
How to display more columns in BlackBerry Manager The following additional columns are available in the Users tab in BlackBerry® Manager to help BlackBerry® Enterprise Server administrators audit their environment. Column Name Description…
Free/busy lookups fail in an Exchange 2007 environment Free/busy lookup will fail on BlackBerry® smartphones and the following error may be seen in the Microsoft® Messaging Agent log file: [Microsoft Exchange Server Information Store -…
How to enable extended BlackBerry Manager logging Standard Logging levels for the BlackBerry® Manager can be changed in the BlackBerry Server Configuration panel Logging tab like many other BlackBerry Enterprise Server Log files. For…
Unable to restore the BESMgmt SQL database When restoring the BlackBerry® Enterprise Service Management database through Microsoft® SQL Server® Management Studio, the database cannot be restored. The error message “exclusive access could…
SMS message size and data coding The maximum allowable number of characters in a Short Message Service (SMS) message depends on the data coding scheme set on the BlackBerry® smartphone. The following list reflects the maximum allowable…
ID: KB15293 | Published: 5/16/11 |
BlackBerry Enterprise supported mirroring modes The recommended mirroring mode for the BlackBerry® Enterprise Server is High safety with automatic failover (synchronous) mode. There are two other mirroring modes available: · High…
Web-based BlackBerry Device Software updates BlackBerry® smartphone users have the option of updating the BlackBerry Device Software on their BlackBerry smartphones using web-based technology available on the BlackBerry Device Software…
Value-added applications for BlackBerry smartphones The following applications are classed as value-added on BlackBerry® smartphones. BlackBerry® Enterprise Server administrators can deploy these applications using the application control…
What is the EWSTest.exe utility The EWSTest.exe utility can be used to test the configuration of Active Directory and the Microsoft® Exchange Client Access Server for Exchange Web Service operations. The utility can be run standalone and is…
ID: KB26140 | Published: 5/11/11 |
Troubleshooting Java processes using jstack Java® processes cannot be debugged using standard debugging tools (Userdump, DebugDiag, ADPlus, WindDBG etc) that you may be familiar with. Any process dump taken from a Java process using the…
Mail delays when using Microsoft Exchange 2010 There is an increasing trend with customers who are migrating to BlackBerry® Enterprise Server for Microsoft® Exchange 2010 and begin to experience extreme messaging delays. These delays can be…
How to locate the BlackBerry Enterprise Server Debug Logs The default location of debug logs generated by various editions of the BlackBerry® Enterprise Server is: 64-bit server: C:Program Files (x86)Research In MotionBlackBerry…
How to perform an email reconciliation test An email reconciliation test should be run if a BlackBerry® smartphone user reports email messages that have been opened, moved, or deleted in Novell® GroupWise®, Microsoft® Exchange, or IBM®…
How to configure LDAP for the BlackBerry Enterprise Server The LDAPDomain, LDAPSearch, LDAPport, LDApssl, LDAPALPSearch, and LDAPPIMSearchregistry entries are used to configure the Lightweight Directory Access Protocol (LDAP) for the…
ID: KB03193 | Published: 5/5/11 |
Visibility of the BCC field on the BlackBerry smartphone The BCC or “Blind Carbon Copy” field may or may not be displayed within received email messages. The BCC field’s visibility on the Bla ckBerry® smartphone in a BlackBerry® Enterprise…
Unable to add users from company directory Administrators may notice newly created entries in the company directory are not imported into dbo.MSAddresses SQL table in a timely manner and when adding new users to the BlackBerry® Ent erprise…
Testing of Global Catalog Referrals 1) Log in to the BlackBerry® Enterprise Server as the service account. 2) Stop the BlackBerry Enterprise Server Services. 3) Make the changes in KB16118…
What should be considered when choosing to install DBNS Without any BlackBerry® smartphone user activity, the BlackBerry® Enterprise Server produces about 1500 query statements per hour. The number of query statements can be reduced by 50…
Data limitations for wireless calendar synchronization When a calendar appointment is created on the BlackBerry® smartphone, the first 4096 characters entered in the notes field will be synchronized with the mail client. The *notes* field…
March 2011: Daylight Savings Time Update The March 2011 Daylight Savings Time (DST) update is cumulative and includes updates to the following Time Zones: Country Time Zone DST Start DST End Chile* Santiago (GMT -4)* Midnight between…
How to switch BlackBerry Enterprise Server service accounts To change the BlackBerry® Enterprise Server service account for the BlackBerry Enterprise Server for Microsoft® Exchange, complete the following tasks: Summary of Tasks 1) Create a…
Seeing network errors when opening Google Maps When opening Google Maps™ on a BlackBerry® smartphone the following error appears: Network error. Your enerprise Blackberry server does not allow connections to the Google Maps service ·…
ID: KB26752 | Published: 4/28/11 |
Daylight Savings Time – Egypt 2011 On April 20, 2011 the Egyptian government announced that Daylight Savings Time will not be observed. Daylight Savings Time was orginally scheduled to start on April 29, 2011. · BlackBerry® Enterprise…
How To Submit BlackBerry Enterprise Server Debug Logs Sometimes for troubleshooting purposes the BlackBerry® Enterprise Server Debug Logs will be required to be reviewed by Technical Support Teams. The default location for the logs is in…
How to uninstall the BlackBerry MDS Integration Service The BlackBerry® Mobile Data System Integration Service was used in previous versions of BlackBerry® Enterprise Server to develop and deploy custom applications for integration with…
Temporary CALS for BlackBerry Enterprise Server software Temporary Client Access Licenses (CALs), for BlackBerry® Enterprise Server software for Microsoft® Exchange, can be requested by customers, resellers and carriers. These CALs are…
Unable to send a MMS message from the BlackBerry smartphone The BlackBerry® smartphone user is unable to send Multimedia Message Service (MMS) messages. · BlackBerry® Enterprise Server 4.1 to 5.0 SP1 · BlackBerry® Device Software 4.1 to 5.0…
What is a BlackBerry Orphaned Contacts folder? The “BlackBerry® Orphaned Contacts” folder information is created when the mail agent gets an “addContact” request from the device during a slow sync or activation, and the when folderID…
BlackBerry Enterprise Server services errors The following errors are logged in the BlackBerry® Enterprise Server logs and the Windows® Event Viewer™ logs for the BlackBerry Enterprise Server services. The lists are divided into three…
How to disable Internet Browser on BlackBerry smartphones To disable the Internet Browser on BlackBerry smartphones, perform the following: 1) In the BlackBerry Manager, in the left pane, click BlackBerry Domain. 2) On the Global tab, click…
ID: KB10936 | Published: 4/19/11 |
How to download and manually update the cdo.dll file To download and manually update the cdo.dll file, complete the following tasks: Note: Before applying the cdo.dll file, verify that the most recent service pack for the M icrosoft®…
Turning off external services disables the browser push Turning off ‘External services for selected devices’ disables a browser push or a bookmark push for that BlackBerry smartphone. · BlackBerry® smartphones When attempting to do a…
ID: KB26002 | Published: 4/18/11 |
IT policies introduced in BlackBerry Device Software 6.0 With the introduction of BlackBerry® Device Software 6.0, the following IT policies are available to BlackBerry Enterprise Server administrators. For instructions on how to import…
Configure a VPN profile on the BlackBerry smartphone A virtual private network (VPN) profile contains the user account information required to log in to a VPN. Note: To be valid, the VPN profile created on the BlackBerry® smartphone must…
Global Address List fields When a Global Address List (GAL) lookup is performed from a BlackBerry® smartphone, the BlackBerry® Enterprise Server queries the following fields within the Microsoft® Active Directory® schema: Field Value…
How to use the Erase Data and Disable Handheld command The Erase Data and Disable Handheld command can be sent to a BlackBerry® smartphone over the wireless network to erase all data and disable it so that it is no longer connected to the…
April 2011 Daylight Savings Time Update for Chile The Chilean government has announced that Daylight Savings Time will now end at midnight between May 7 and 8, 2011. This update also contains the changes from the March 2011 Daylight Savings…
ID: KB26394 | Published: 4/4/11 |
How to add or change the auto signature feature The signature appears at the bottom of email messages sent from the BlackBerry® smartphone. The signature can be added or changed using the BlackBerry® Desktop Manager, the BlackBerry®…
ID: KB02035 | Published: 4/4/11 |
Allow BlackBerry Enterprise Server SNMP traffic To enable Simple Network Management Protocol (SNMP) traffic on the BlackBerry Enterprise Server, complete the following: 1) Open the Registry Editor and go to…
955572 You cannot cache shared mail folders in Outlook 2007
April 10, 2011
2534447 E-mail attachments are not visible to some recipients
2534468 How to delete corrupted and hidden rules from a single mailbox in Outlook 2003
2534494 The public subfolder that you add to your Favorites public folder does not appear in Outlook 2007 or in Outlook 2003
2534496 The Visual Basic Editor may open without menus or toolbars in Outlook 2007 or in Outlook 2003
2534459 You receive an “Insufficient Disk Space” error message when you install Outlook 2007 with Business Contact Manager or Outlook 2003 with Business Contact Manager
2534460 You cannot hide or show the Business Contact Manager toolbar in Outlook 2007 or in Outlook 2003
2522999 Description of the Office Outlook 2007 Junk Email Filter update: April 12, 2011
2534478 Error message when you try to import or to export files in Outlook: “Microsoft Outlook cannot start the required translator”
2534479 How to troubleshoot Search Folders in Outlook 2010, Outlook 2007, and Outlook 2003
2534504 How to send e-mail messages that remain in your Outbox in Outlook
2534505 When you send an e-mail message from a shared mailbox in Outlook 2007, the sent message is not saved in the Sent Items folder of the shared mailbox
2534514 How to configure Outlook to receive e-mail messages from an IMAP server
2534448 After you configure one or more client-only message rules in Outlook, other message rules do not take effect
2534469 You may receive an error message and Outlook does not start when you try to start Outlook on a computer that is running Windows XP
2534513 How to find and run the Inbox Repair tool in Outlook
April 12, 2011
2522981 Description of the Office Outlook 2003 Junk Email Filter update: April 12, 2011
April 20, 2011
972148 When you send an e-mail message from a shared mailbox in Outlook 2007, the sent message is not saved in the Sent Items folder of the shared mailbox
May 3, 2011
2468058 Credentials prompt not shown with Outlook 2010 deployed as a RemoteApp
May 9, 2011
974498 What to do if the size of your Outlook data file increases over time and causes issues
May 10, 2011 2536411 Description of the Office Outlook 2003 Junk Email Filter update: May 10, 2011
May 13, 2011
2537249 You receive error messages when you turn on the logging feature in Office Communicator 2007 R2 after you install cumulative update KB 2291453
2516293 Outlook 2010 stops responding when you try to open a RMS-protected email message that has a large attachment
May 20, 2011
2555528 Unable to save Outlook email attachment to network share or external memory device
2540106 Description of the Outlook 2010 hotfix package (Outlook-x-none.msp): May 2, 2011
May 25, 2011
2482432 An external federated user who uses a proxy that has Digest authentication enabled cannot join a Live Meeting by using Office Live Meeting 2007
2536682 “An error occurred while sending the e-mail invitation” error message when you click “by E-mail” in a Live Meeting 2007 client
2536683 Description of the update package for the Windows-based Live Meeting 2007 client: May 2011
2537295 The JAWS screen reader cannot read certain items in a Live Meeting when you use a Live Meeting 2007 client
May 26, 2011
2497077 Outlook 2007 or Outlook 2010 displays incorrect search results of a GAL in Exchange Server 2007 or in Exchange Server 2010
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* New On-DemandWeb Contentfrom April 2011
TechNet Webcast: Introducing Office 365 to Your End Users (Level 100)
Are you planning on rolling out Microsoft Office 365 to your organization? You’re familiar with the back-end cloud benefits, but how does Office 365 affect your users? In this fast-paced 60-minute presentation, we discuss strategy to make sure that your business captures the productivity gains that are possible with Office 365. Topics include planning pre-rollout training, generating excitement among your users, easing the tension of deployment day, and providing ongoing resources. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032486368&EventCategory=5&culture=en-US&CountryCode=US
Business Insights Webcast: BPOS to Office 365 Transition (Part 1 of 2): New Features, Experiences and Requirements Join us for both events in this series as Microsoft Office 365 delivers the power of cloud productivity to businesses of all sizes. Office 365 combines the familiar Microsoft Office suite with cloud-based versions of next-generation communications and collaboration services: Microsoft Exchange Online, Microsoft SharePoint Online, and Microsoft Lync Online. Give your people new ways to collaborate on documents, the ability to work online or offline, and access to their documents, email, calendars from any device. This webcast details guidance for the transition from Microsoft Business Productivity Online Suite (BPOS) to Office 365, the requirements for Office 365, and administrator tasks for getting your organization ready for Office 365 https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032484649&EventCategory=5&culture=en-US&CountryCode=US
MSDN Webcast: Cloud Power Event Series (Part 1 of 5): Data Migration to the Cloud (Level 200)
Data migration to the Cloud. Few things have as much value in the digital age as good old data. Unfortunately, it is often scattered and not necessarily running on infrastructure that’s up to date. In this session, you will learn about the challenge of having data sitting on “intermittently maintained infrastructure” and how best to migrate to a cloud environment that is persistently up to date. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032486464&EventCategory=5&culture=en-US&CountryCode=US
TechNet Webcast: End User Tips and Tricks for Office 365: Focus on SharePoint Online (Level 100)
Are you wondering what Microsoft SharePoint Online is and how it impacts your organization? Are you curious about what role it can play in your employees’ productivity experience? Join us for a fast-paced 60-minute session that is designed to highlight the most exciting features of SharePoint Online. An instructor showcases a tip or a feature every few minutes, which provides you with a broad and real-world understanding of what the platform can do for your users. Topics include collaborating with team sites, simplifying document access through Microsoft Office Web Apps, coauthoring content by using Microsoft Office and SharePoint Online, automating business processes, and improving communication with Microsoft Lync Online integration. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032486370&EventCategory=5&culture=en-US&CountryCode=US
TechNet Webcast: End User Tips and Tricks for Office 365: Exchange Online with Email (Level 100) Are you wondering what Microsoft Exchange Online is and how it impacts your organization? Are you curious about what role it can play in your employees’ productivity experience? Join us for a fast-paced 60-minute session that is designed to highlight the most exciting features of Exchange Online. An instructor showcases a tip or a feature every few minutes, which provides you with a broad and real-world understanding of what the platform can do for your users. Topics include organizing your inbox in Microsoft Outlook 2010, connecting with your contacts, accessing your email anywhere on any device, and keeping track of your day in Outlook 2010. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032486201&EventCategory=5&culture=en-US&CountryCode=US
Business Insights Webcast: BPOS to Office 365 Transition (Part 2 of 2): Administration Steps and Experience (Level 100) Join us for both events in this series as Microsoft Office 365 introduces new online services and capabilities, new user experiences, and new online platform capabilities. It also introduces new underlying server software into Microsoft Online Services data centers as well as other major new service and platform investments. The name may be new and includes new offerings, but you are subscribed to the same service, just significantly enhanced. In this webcast, we work through the changes in the administration of Office 365 from Microsoft Business Productivity Online Suite (BPOS), client requirements and deployment options, and transition guidance from the IT perspective. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032484651&EventCategory=5&culture=en-US&CountryCode=US
TechNet Webcast: End User Tips and Tricks for Office 365: Get the Most out of Lync Online (Level 100) Are you wondering what Microsoft Lync Online is and how it impacts your organization? Are you curious about what role it can play in your employees’ productivity experience? Join us for a fast-paced 60-minute session that is designed to highlight the most exciting features of Lync Online. An instructor showcases a tip or a feature every few minutes, which provides you with a broad and real-world understanding of what the platform can do for your users. Topics include viewing Lync Online presence in your applications, managing conversations, sharing your desktop with others, and hosting an online meeting. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032486203&EventCategory=5&culture=en-US&CountryCode=US
Microsoft Office System Webcast: Tips and Tricks for OneNote and Outlook 2010 (Level 100) We invite you to attend a Live Meeting presentation that will help you get the most out of OneNote and Outlook 2010. Learn about new features and timesavers to help you in your day-to-day work. This session is good for beginner and intermediate users.
TechNet Webcast: Forefront Protection for Office: Cloud Protection Technologies (Level 300)
Learn how to best protect your email by using Microsoft Forefront Online Protection for Exchange. Hear about core Forefront Online Protection for Exchange capabilities, such as multiple-engine antivirus protection, antispam protection, and policy definition, that help keep your customer email collaboration more secure. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032481080&EventCategory=5&culture=en-US&CountryCode=US
TechNet Webcast: Forefront Online Protection for Exchange Routing Scenarios (Level 300) This webcast takes a deep dive into the new capabilities of the next release of Microsoft Forefront Online Protection for Exchange. New customers that use the Microsoft Office 365 cloud-based application suite and Business Productivity Online Suite (BPOS) will be able to route mail through Forefront Online Protection for Exchange for filtering. All Forefront Online Protection for Exchange customers will be able to configure secure cross-premises hybrid mail-flow scenarios that can help them seamlessly move mail infrastructure to the cloud while maintaining existing investments and configuration. This webcast presents and demonstrates these scenarios and describes the underlying architecture. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032481082&EventCategory=5&culture=en-US&CountryCode=US
Business Insights Webcast: BPOS to Office 365 Transition (Part 2 of 2): Administration Steps and Experience (Level 100) Join us for both events in this series as Microsoft Office 365 introduces new online services and capabilities, new user experiences, and new online platform capabilities. It also introduces new underlying server software into Microsoft Online Services data centers as well as other major new service and platform investments. The name may be new and includes new offerings, but you are subscribed to the same service, just significantly enhanced. In this webcast, we work through the changes in the administration of Office 365 from Microsoft Business Productivity Online Suite (BPOS), client requirements and deployment options, and transition guidance from the IT perspective. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032484763&EventCategory=5&culture=en-US&CountryCode=US
TechNet Webcast: Forefront Online Protection for Exchange and Office 365 (Level 300) Microsoft Forefront Online Protection for Exchange and Microsoft Office 365 are better together. See how the new features in Forefront Online Protection for Exchange 11.1 help Office 365 customers simplify the management experience through a single sign on (SSO). Also, learn how the new inbound and outbound advanced routing scenarios in Forefront Online Protection for Exchange help Office 365 customers optimize their email flow requirements. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032481084&EventCategory=5&culture=en-US&CountryCode=US
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* Webcasts of interest showing at a desktop near you in June 2011
Friday, June 03, 2011 TechNet Webcast: Talk TechNet with Keith Combs and Matt Hester – Episode 34: PowerShell with Sean Kearney (Level 200) Call in or join us on the web as we host Sean Kearney, Microsoft PowerShell MVP. Sean is the “Energized about IT” guy and you’ll find him frequently blogging at http://ye110wbeard.wordpress.com/. Last time we had Sean on the show he broke into a series of demos on Live Meeting. Now technically this is a talk show, but keep that in mind just in case he decides to get energetic again. Be sure to take advantage of this unique opportunity to get some questions answered. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032487714
Monday, June 06, 2011 TechNet Webcast: Virtualizing Exchange Server with Hyper-V: Better Together (Level 200)
This webcast covers virtualization scenarios for Microsoft Exchange 2010 and how the combination of Hyper-V and Microsoft System Center solves the issues. We also discuss the various deployment scenarios for Exchange and perform a deep dive on virtualizing it with Hyper-V. The presentation highlights examples of Exchange performance on Hyper-V and best practices for a successful deployment. Finally, we also touch upon partner solutions, including the PRO packs and how these solutions enhance the benefits of running Exchange virtually. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486375
Tuesday, June 07, 2011 TechNet Webcast: Lync Server 2010 Architecture Topologies (Level 200)
In this webcast, we describe the overall architecture of Microsoft Lync Server 2010 and the key considerations for the scalability and performance of each server role. This webcast provides the background and framework for the other Lync Server 2010 webcasts and serves as a bridge between the overview session and the drill-downs in the different product areas. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486206
Thursday, June 09, 2011 TechNet Webcast: Lync Server 2010: Migration and Coexistence (Level 300)
In this webcast, we explore the path of moving from Microsoft Office Communications Server 2007 R2 to Microsoft Lync Server 2010. Although some of the technical functionalities of the products are similar, these are two very different products. Join this webcast to prepare yourself for a successful migration from Communications Server 2007 R2 to Lync Server 2010. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486208
Monday, June 13, 2011 TechNet Webcast: Cybercriminals Using Marketing-Like Approaches to Target Consumers (Level 200)
Microsoft has released the latest Security Intelligence Report (SIR v10). Volume 10 uncovers evolving threat landscape trend information from more than 600 million systems worldwide, focusing on the second half of 2010. In addition, there are 117 global threat assessments, which help make SIR v10 the most comprehensive compilation of malware information in the world. In this webcast, Frank Simorjay discusses SIR v10. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032488101
Wednesday, June 15, 2011 TechNet Webcast: Lync Server 2010: Role-Based Access Control (RBAC) (Level 300)
In this webcast, we introduce the Microsoft Lync Server 2010 Management Shell, a new method of administration and management. The Lync Server 2010 Management Shell is a powerful management interface built on the Windows PowerShell command-line interface, which includes a comprehensive set of cmdlets that are specific to Lync Server 2010. We take a look at various commands and how to perform various management tasks by using the Lync Server 2010 Management Shell. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486210
Thursday, June 16, 2011 Business Insights Webcast: Cloud Productivity for Enterprises Featuring Microsoft Office 365 (Level 100) Microsoft Office 365 delivers the power of cloud productivity to businesses of all sizes, helping to save time and money and to free up valued resources. Office 365 combines the familiar Office desktop suite with cloud-based versions of Microsoft’s next-generation communications and collaboration services: Microsoft Exchange Online, Microsoft SharePoint Online, and Microsoft Lync Online. Office 365 is simple to use, easy to administer, and backed by the robust security and guaranteed reliability you expect from a world-class service provider. See an overview of all the products and services of Office 365, pricing and licensing concepts, and a demonstration of the future of productivity. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032479775
Friday, June 17, 2011 TechNet Webcast: Lync Server 2010: Implementing Call-Admission Control (Level 300)
Real-time communications are sensitive to the latency and packet loss that can occur on congested networks. Call-Admission Control (CAC) determines, based on available network bandwidth, whether to allow real-time communication sessions such as voice or video calls to be established. During this webcast, we go through the planning aspects to prepare you for the implementation of CAC. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486213
Friday, June 10, 2011 TechNet Webcast: How to Build a Private Cloud (Part 1): An Overview of a Private Cloud (Level 100)
In this session, we discuss the emergence of a private cloud as the logical next step in virtualization and the amazing benefits that you can get by automating IT services in your organization. We compare and contrast hosted versus on-premises private cloud options and discuss the advantages and drawbacks of each. We also discuss the tools and techniques that you need to build your own private cloud. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032487286
Friday, June 17, 2011 TechNet Webcast: How to Build a Private Cloud (Part 2): Hyper-V, the Backbone of a Private Cloud (Level 200) In this session, we demonstrate some of the key functionalities of Hyper-V that make it ideally suited to perform IT as a service and private cloud functions. We walk through a demonstration of installing and configuring Hyper-V for a private cloud and discuss some of the important considerations of running Hyper-V in this environment. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032487288
Friday, June 24, 2011 TechNet Webcast: How to Build a Private Cloud (Part 3): System Center, the Nerve Center of a Private Cloud (Level 200)
In this session, we discuss the key functions of the Microsoft System Center tools as the nerve center for your private cloud. We talk about System Center Operations Manager and System Center Virtual Machine Manager. We demonstrate how to install and configure each of these into a private cloud and demonstrate their effectiveness as the management tools for private cloud environments. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032487294
Wednesday, June 29, 2011 TechNet Webcast: How to Build a Private Cloud (Part 4): The Self-Service Portal, the Muscles of a Private Cloud (Level 200)
In this session, we discuss the self-service portal and demonstrate how to install, configure, and potentially use it in a private cloud. We demonstrate how to configure and implement virtual machine roles in a private cloud and how you can use the self-service portal to easily maintain and update those roles. Finally, we discuss how to use Windows Azure Connect to integrate your private cloud with the public cloud. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032487333
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* New On-DemandWeb Contentfrom April 2011
TechNet Webcast: Forefront Online Protection for Exchange Encryption Overview (Level 300) Regardless of whether customers are on premises, in the cloud, or both, they all face challenges in email protection and how to distribute information. Learn how identity-based encryption is integrated into Microsoft Exchange Hosted Encryption and how businesses can use this service to easily send and receive ad hoc encrypted communication. This webcast provides a technical overview of the Microsoft Forefront Online Protection for Exchange Encryption Service. We review its core components and functionality, including its prerequisites, product architecture, and capabilities. Learn about the components, and get tips for how to deliver successful Forefront Online Protection for Exchange demos. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032481195&EventCategory=5&culture=en-US&CountryCode=US
Business Insights Webcast: Building the Business Case for the Cloud (Level 100) In this webcast, we focus on a process for building a business plan for cloud computing development and migration. The discussion will focus on how to calculate return on investment (ROI) and total cost of ownership (TCO) in cloud computing, and will describe ideal workloads. Case studies will also be discussed and new cloud-enabled business models explored. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032484240&EventCategory=5&culture=en-US&CountryCode=US
#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#* Webcasts of interest showing at a desktop near you in May 2011
TechNet Webcast: Introducing Office 365 to Your End Users (Level 100) Are you planning on rolling out Microsoft Office 365 to your organization? You’re familiar with the back-end cloud benefits, but how does Office 365 affect your users? In this fast-paced 60-minute presentation, we discuss strategy to make sure that your business captures the productivity gains that are possible with Office 365. Topics include planning pre-rollout training, generating excitement among your users, easing the tension of deployment day, and providing ongoing resources. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486368
Business Insights Webcast: Best of Microsoft Management Summit 2011: Virtualization, Management, and the Cloud (Level 100) As the data center and the IT organization at large become increasingly complex, and especially as virtualization drives server sprawl, management becomes a critical component of an IT organization’s value proposition. Having a common management platform, such as the Microsoft System Center management platform, lets an IT organization streamline its management processes and resources, resulting in efficiency and effectiveness. This webcast highlights the various components of the System Center suite and demonstrates how a common management platform can propel your IT organization forward. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032483707
Business Insights Webcast: BPOS to Office 365 Transition (Part 1 of 2): New Features, Experiences and Requirements Join us for both events in this series as Microsoft Office 365 delivers the power of cloud productivity to businesses of all sizes. Office 365 combines the familiar Microsoft Office suite with cloud-based versions of next-generation communications and collaboration services: Microsoft Exchange Online, Microsoft SharePoint Online, and Microsoft Lync Online. Give your people new ways to collaborate on documents, the ability to work online or offline, and access to their documents, email, calendars from any device. This webcast details guidance for the transition from Microsoft Business Productivity Online Suite (BPOS) to Office 365, the requirements for Office 365, and administrator tasks for getting your organization ready for Office 365. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032484649
TechNet Webcast: Information About Microsoft May Security Bulletins (Level 200) Join us for a brief overview of the technical details of the May security bulletins. We intend to address your concerns in this webcast, therefore, most of the webcast is devoted to attendees asking questions about the bulletins and getting answers from Microsoft security experts. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032455072
TechNet Webcast: End User Tips and Tricks for Office 365: Focus on SharePoint Online (Level 100) Are you wondering what Microsoft SharePoint Online is and how it impacts your organization? Are you curious about what role it can play in your employees’ productivity experience? Join us for a fast-paced 60-minute session that is designed to highlight the most exciting features of SharePoint Online. An instructor showcases a tip or a feature every few minutes, which provides you with a broad and real-world understanding of what the platform can do for your users. Topics include collaborating with team sites, simplifying document access through Microsoft Office Web Apps, coauthoring content by using Microsoft Office and SharePoint Online, automating business processes, and improving communication with Microsoft Lync Online integration. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486370&CountryCode=US
Business Insights Webcast: Cloud Productivity Featuring Microsoft SharePoint Online (Level 100) The capabilities of Microsoft SharePoint Online work together with Microsoft Office Professional Plus 2010 to help your company quickly respond to changing business needs. Using SharePoint Online and Office Professional Plus 2010, your people can share ideas and expertise, create custom solutions for specific needs, and find the right business information to make better decisions. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032479680&CountryCode=US
TechNet Webcast: End User Tips and Tricks for Office 365: Exchange Online with Email (Level 100) Are you wondering what Microsoft Exchange Online is and how it impacts your organization? Are you curious about what role it can play in your employees’ productivity experience? Join us for a fast-
paced 60-minute session that is designed to highlight the most exciting features of Exchange Online. An instructor showcases a tip or a feature every few minutes, which provides you with a broad and real-world understanding of what the platform can do for your users. Topics include organizing your inbox in Microsoft Outlook 2010, connecting with your contacts, accessing your email anywhere on any device, and keeping track of your day in Outlook 2010. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486201&CountryCode=US
Business Insights Webcast: BPOS to Office 365 Transition (Part 2 of 2): Administration Steps and Experience (Level 100) Join us for both events in this series as Microsoft Office 365 introduces new online services and capabilities, new user experiences, and new online platform capabilities. It also introduces new underlying server software into Microsoft Online Services data centers as well as other major new service and platform investments. The name may be new and includes new offerings, but you are subscribed to the same service, just significantly enhanced. In this webcast, we work through the changes in the administration of Office 365 from Microsoft Business Productivity Online Suite (BPOS), client requirements and deployment options, and transition guidance from the IT perspective. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032484651&CountryCode=US
TechNet Webcast: End User Tips and Tricks for Office 365: Get the Most out of Lync Online (Level 100) Are you wondering what Microsoft Lync Online is and how it impacts your organization? Are you curious about what role it can play in your employees’ productivity experience? Join us for a fast-paced 60-minute session that is designed to highlight the most exciting features of Lync Online. An instructor showcases a tip or a feature every few minutes, which provides you with a broad and real-world understanding of what the platform can do for your users. Topics include viewing Lync Online presence in your applications, managing conversations, sharing your desktop with others, and hosting an online meeting. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032486202
Wednesday, May 18, 2011: TechNet Webcast: The Forefront Online Protection for Exchange Management Experience (Level 300) Learn best practices for how to use the Microsoft Forefront Online Protection for Exchange Administration Center. In this webcast, get tips and tricks from experts about key product capabilities and how to effectively manage Forefront Online Protection for Exchange. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032481085
Wednesday, May 18, 2011: TechNet Webcast: Forefront Online Protection for Exchange Routing Scenarios (Level 300) This webcast takes a deep dive into the new capabilities of the next release of Microsoft Forefront Online Protection for Exchange. New customers that use the Microsoft Office 365 cloud-based application suite and Business Productivity Online Suite (BPOS) will be able to route mail through Forefront Online Protection for Exchange for filtering. All Forefront Online Protection for Exchange customers will be able to configure secure cross-premises hybrid mail-flow scenarios that can help them seamlessly move mail infrastructure to the cloud while maintaining existing investments and configuration. This webcast presents and demonstrates these scenarios and describes the underlying architecture. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032481081
Tuesday, May 24, 2011: TechNet Webcast: Forefront Online Protection for Exchange and Office 365 (Level 300) Microsoft Forefront Online Protection for Exchange and Microsoft Office 365 are better together. See how the new features in Forefront Online Protection for Exchange 11.1 help Office 365 customers simplify the management experience through a single sign on (SSO). Also, learn how the new inbound and outbound advanced routing scenarios in Forefront Online Protection for Exchange help Office 365 customers optimize their email flow requirements. https://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?culture=en-US&EventID=1032481083