summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/editor/plugins/AutoUrlLink.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo-1.7.2/dojox/editor/plugins/AutoUrlLink.js')
-rw-r--r--js/dojo-1.7.2/dojox/editor/plugins/AutoUrlLink.js235
1 files changed, 235 insertions, 0 deletions
diff --git a/js/dojo-1.7.2/dojox/editor/plugins/AutoUrlLink.js b/js/dojo-1.7.2/dojox/editor/plugins/AutoUrlLink.js
new file mode 100644
index 0000000..ee126cd
--- /dev/null
+++ b/js/dojo-1.7.2/dojox/editor/plugins/AutoUrlLink.js
@@ -0,0 +1,235 @@
+//>>built
+define("dojox/editor/plugins/AutoUrlLink", [
+ "dojo",
+ "dijit",
+ "dojox",
+ "dijit/_editor/range",
+ "dijit/_editor/selection",
+ "dijit/_editor/_Plugin",
+ "dijit/form/Button",
+ "dojo/_base/connect",
+ "dojo/_base/declare",
+ "dojo/string"
+], function(dojo, dijit, dojox) {
+
+dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
+ //summary:
+ // This plugin can recognize a URL like string
+ // (such as http://www.website.com) and turn it into
+ // a hyperlink that points to that URL.
+
+ // _template [private] String
+ // The link template
+ _template: "<a _djrealurl='${url}' href='${url}'>${url}</a>",
+
+ setEditor: function(/*dijit.Editor*/ editor){
+ // summary:
+ // Called by the editor it belongs to.
+ // editor:
+ // The editor it belongs to.
+ this.editor = editor;
+ if(!dojo.isIE){
+ // IE will recognize URL as a link automatically
+ // No need to re-invent the wheel.
+ dojo.some(editor._plugins, function(plugin){
+ // Need to detect which enter key mode it is now
+ if(plugin.isInstanceOf(dijit._editor.plugins.EnterKeyHandling)){
+ this.blockNodeForEnter = plugin.blockNodeForEnter;
+ return true;
+ }
+ return false;
+ }, this);
+ this.connect(editor, "onKeyPress", "_keyPress");
+ this.connect(editor, "onClick", "_recognize");
+ this.connect(editor, "onBlur", "_recognize");
+ }
+ },
+
+ _keyPress: function(evt){
+ // summary:
+ // Handle the keypress event and dispatch it to the target handler
+ // evt:
+ // The keypress event object.
+ // tags:
+ // protected
+ var ks = dojo.keys, v = 118, V = 86,
+ kc = evt.keyCode, cc = evt.charCode;
+ if(cc == ks.SPACE || (evt.ctrlKey && (cc == v || cc == V))){
+ setTimeout(dojo.hitch(this, "_recognize"), 0);
+ }else if(kc == ks.ENTER){
+ // Handle the enter event after EnterKeyHandling finishes its job
+ setTimeout(dojo.hitch(this, function(){
+ this._recognize({enter: true});
+ }), 0);
+ }else{
+ // _saved: The previous dom node when the cursor is at a new dom node.
+ // When we click elsewhere, the previous dom node
+ // should be examed to see if there is any URL need to be activated
+ this._saved = this.editor.window.getSelection().anchorNode;
+ }
+ },
+
+ _recognize: function(args){
+ // summary:
+ // Recognize the URL like strings and turn them into a link
+ // tags:
+ // private
+ var template = this._template,
+ isEnter = args ? args.enter : false,
+ ed = this.editor,
+ selection = ed.window.getSelection();
+ if(selection){
+ var node = isEnter ? this._findLastEditingNode(selection.anchorNode) :
+ (this._saved || selection.anchorNode),
+ bm = this._saved = selection.anchorNode,
+ bmOff = selection.anchorOffset;
+
+ if(node.nodeType == 3 && !this._inLink(node)){
+ var linked = false, result = this._findUrls(node, bm, bmOff),
+ range = ed.document.createRange(),
+ item, cost = 0, isSameNode = (bm == node);
+
+ item = result.shift();
+ while(item){
+ // Covert a URL to a link.
+ range.setStart(node, item.start);
+ range.setEnd(node, item.end);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ ed.execCommand("insertHTML", dojo.string.substitute(template, {url: range.toString()}));
+ cost += item.end;
+ item = result.shift();
+ linked = true;
+ }
+
+ // If bm and node are the some dom node, caculate the actual bookmark offset
+ // If the position of the cursor is modified (turned into a link, etc.), no
+ // need to recover the cursor position
+ if(isSameNode && (bmOff = bmOff - cost) <= 0){ return; }
+
+ // We didn't update anything, so don't collapse selections.
+ if(!linked) { return ; }
+ try{
+ // Try to recover the cursor position
+ range.setStart(bm, 0);
+ range.setEnd(bm, bmOff);
+ selection.removeAllRanges();
+ selection.addRange(range);
+ dojo.withGlobal(ed.window, "collapse", dijit._editor.selection, []);
+ }catch(e){}
+ }
+ }
+ },
+
+ _inLink: function(/*DomNode*/ node){
+ // summary:
+ // Check if the node is already embraced within a <a>...</a> tag.
+ // node:
+ // The node to be examed.
+ // tags:
+ // private
+ var editNode = this.editor.editNode,
+ result = false, tagName;
+
+ node = node.parentNode;
+ while(node && node !== editNode){
+ tagName = node.tagName ? node.tagName.toLowerCase() : "";
+ if(tagName == "a"){
+ result = true;
+ break;
+ }
+ node = node.parentNode;
+ }
+ return result;
+ },
+
+ _findLastEditingNode: function(/*DomNode*/ node){
+ // summary:
+ // Find the last node that was edited so that we can
+ // get the last edited text.
+ // node:
+ // The current node that the cursor is at.
+ // tags:
+ // private
+ var blockTagNames = dijit.range.BlockTagNames,
+ editNode = this.editor.editNode, blockNode;
+
+ if(!node){ return node; }
+ if(this.blockNodeForEnter == "BR" &&
+ (!(blockNode = dijit.range.getBlockAncestor(node, null, editNode).blockNode) ||
+ blockNode.tagName.toUpperCase() != "LI")){
+ while((node = node.previousSibling) && node.nodeType != 3){}
+ }else{
+ // EnterKeyHandling is under "DIV" or "P" mode or
+ // it's in a LI element. Find the last editing block
+ if((blockNode || (blockNode = dijit.range.getBlockAncestor(node, null, editNode).blockNode)) &&
+ blockNode.tagName.toUpperCase() == "LI"){
+ node = blockNode;
+ }else{
+ node = dijit.range.getBlockAncestor(node, null, editNode).blockNode;
+ }
+ // Find the last editing text node
+ while((node = node.previousSibling) && !(node.tagName && node.tagName.match(blockTagNames))){}
+ if(node){
+ node = node.lastChild;
+ while(node){
+ if(node.nodeType == 3 && dojo.trim(node.nodeValue) != ""){
+ break;
+ }else if(node.nodeType == 1){
+ node = node.lastChild;
+ }else{
+ node = node.previousSibling;
+ }
+ }
+ }
+ }
+ return node;
+ },
+
+ _findUrls: function(/*DomNode*/ node, /*DomNode*/ bm, /*Number*/ bmOff){
+ // summary:
+ // Find the occurrace of the URL strings.
+ // FF, Chrome && Safri have a behavior that when insertHTML is executed,
+ // the orignal referrence to the text node will be the text node next to
+ // the inserted anchor automatically. So we have to re-caculate the index of
+ // the following URL occurrence.
+ // value:
+ // A text to be scanned.
+ // tags:
+ // private
+ var pattern = /(http|https|ftp):\/\/[^\s]+/ig,
+ list = [], baseIndex = 0,
+ value = node.nodeValue, result, ch;
+
+ if(node === bm && bmOff < value.length){
+ // Break the text so that it may not grab extra words.
+ // Such as if you type:
+ // foo http://foo.com|bar (And | is where you press enter).
+ // It will grab the bar word as part of the link. That's annoying/bad.
+ // Also it prevents recognizing the text after the cursor.
+ value = value.substr(0, bmOff);
+ }
+
+ while((result = pattern.exec(value)) != null){
+ if(result.index == 0 || (ch = value.charAt(result.index - 1)) == " " || ch == "\xA0"){
+ list.push({start: result.index - baseIndex, end: result.index + result[0].length - baseIndex});
+ baseIndex = result.index + result[0].length;
+ }
+ }
+
+ return list;
+ }
+});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+ if(o.plugin){ return; }
+ var name = o.args.name.toLowerCase();
+ if(name === "autourllink"){
+ o.plugin = new dojox.editor.plugins.AutoUrlLink();
+ }
+});
+
+return dojox.editor.plugins.AutoUrlLink;
+
+});