view release on metacpan or search on metacpan
share/endpoint/www/css/docs.css view on Meta::CPAN
}
img.logo {
position: absolute;
right: -25px;
bottom: 4px;
}
a:link, a:visited, .quasilink {
color: #df0019;
cursor: pointer;
text-decoration: none;
}
a:hover, .quasilink:hover {
color: #800004;
}
h1 a:link, h1 a:visited, h1 a:hover {
color: black;
}
share/endpoint/www/css/sparqlcolors.css view on Meta::CPAN
html {
cursor: text;
}
.editbox {
margin: .4em;
padding: 0;
font-family: monospace;
font-size: 10pt;
color: black;
}
share/endpoint/www/js/codemirror.js view on Meta::CPAN
width: "",
height: "300px",
minHeight: 100,
autoMatchParens: false,
parserConfig: null,
tabMode: "indent", // or "spaces", "default", "shift"
enterMode: "indent", // or "keep", "flat"
electricChars: true,
reindentOnLoad: false,
activeTokens: null,
cursorActivity: null,
lineNumbers: false,
firstLineNumber: 1,
indentUnit: 2,
domain: null,
noScriptCaching: false
});
function addLineNumberDiv(container, firstNum) {
var nums = document.createElement("DIV"),
scroller = document.createElement("DIV");
share/endpoint/www/js/codemirror.js view on Meta::CPAN
this.lineNumbers = addLineNumberDiv(this.wrapping,this.options.firstLineNumber);
this.activateLineNumbers();
}
else if (!on && this.lineNumbers) {
this.wrapping.removeChild(this.lineNumbers);
this.wrapping.style.paddingLeft = "";
this.lineNumbers = null;
}
},
cursorPosition: function(start) {this.focusIfIE(); return this.editor.cursorPosition(start);},
firstLine: function() {return this.editor.firstLine();},
lastLine: function() {return this.editor.lastLine();},
nextLine: function(line) {return this.editor.nextLine(line);},
prevLine: function(line) {return this.editor.prevLine(line);},
lineContent: function(line) {return this.editor.lineContent(line);},
setLineContent: function(line, content) {this.editor.setLineContent(line, content);},
removeLine: function(line){this.editor.removeLine(line);},
insertIntoLine: function(line, position, content) {this.editor.insertIntoLine(line, position, content);},
selectLines: function(startLine, startOffset, endLine, endOffset) {
this.win.focus();
share/endpoint/www/js/codemirror.js view on Meta::CPAN
line = this.prevLine(line);
}
return num;
},
jumpToLine: function(line) {
if (typeof line == "number") line = this.nthLine(line);
this.selectLines(line, 0);
this.win.focus();
},
currentLine: function() { // Deprecated, but still there for backward compatibility
return this.lineNumber(this.cursorLine());
},
cursorLine: function() {
return this.cursorPosition().line;
},
cursorCoords: function(start) {return this.editor.cursorCoords(start);},
activateLineNumbers: function() {
var frame = this.frame, win = frame.contentWindow, doc = win.document, body = doc.body,
nums = this.lineNumbers, scroller = nums.firstChild, self = this;
var barWidth = null;
function sizeBar() {
if (frame.offsetWidth == 0) return;
for (var root = frame; root.parentNode; root = root.parentNode){}
if (!nums.parentNode || root != document || !win.Editor) {
share/endpoint/www/js/codemirror.js view on Meta::CPAN
if (pending) clearTimeout(pending);
if (self.updateNumbers == update) self.updateNumbers = null;
onScroll();
onResize();
};
}
(this.options.textWrapping || this.options.styleNumbers ? wrapping : nonWrapping)();
},
setDynamicHeight: function() {
var self = this, activity = self.options.cursorActivity, win = self.win, body = win.document.body,
lineHeight = null, timeout = null, vmargin = 2 * self.frame.offsetTop;
body.style.overflowY = "hidden";
win.document.documentElement.style.overflowY = "hidden";
this.frame.scrolling = "no";
function updateHeight() {
var trailingLines = 0, node = body.lastChild, computedHeight;
while (node && win.isBR(node)) {
if (!node.hackBR) trailingLines++;
node = node.previousSibling;
share/endpoint/www/js/codemirror.js view on Meta::CPAN
lineHeight = node.offsetHeight;
computedHeight = node.offsetTop + (1 + trailingLines) * lineHeight;
}
else if (lineHeight) {
computedHeight = trailingLines * lineHeight;
}
if (computedHeight)
self.wrapping.style.height = Math.max(vmargin + computedHeight, self.options.minHeight) + "px";
}
setTimeout(updateHeight, 300);
self.options.cursorActivity = function(x) {
if (activity) activity(x);
clearTimeout(timeout);
timeout = setTimeout(updateHeight, 100);
};
}
};
CodeMirror.InvalidLineHandle = {toString: function(){return "CodeMirror.InvalidLineHandle";}};
CodeMirror.replace = function(element) {
share/endpoint/www/js/editor.js view on Meta::CPAN
var span = document.createElement("SPAN");
span.isPart = true;
span.appendChild(value);
span.currentText = text;
return span;
}
function alwaysZero() {return 0;}
// On webkit, when the last BR of the document does not have text
// behind it, the cursor can not be put on the line after it. This
// makes pressing enter at the end of the document occasionally do
// nothing (or at least seem to do nothing). To work around it, this
// function makes sure the document ends with a span containing a
// zero-width space character. The traverseDOM iterator filters such
// character out again, so that the parsers won't see them. This
// function is called from a few strategic places to make sure the
// zwsp is restored after the highlighting process eats it.
var webkitLastLineHack = webkit ?
function(container) {
var last = container.lastChild;
share/endpoint/www/js/editor.js view on Meta::CPAN
function pointAt(node){
var parent = node.parentNode;
var next = node.nextSibling;
return function(newnode) {
parent.insertBefore(newnode, next);
};
}
var point = null;
// This an Opera-specific hack -- always insert an empty span
// between two BRs, because Opera's cursor code gets terribly
// confused when the cursor is between two BRs.
var afterBR = true;
// Insert a normalized node at the current point. If it is a text
// node, wrap it in a <span>, and give that span a currentText
// property -- this is used to cache the nodeValue, because
// directly accessing nodeValue is horribly slow on some browsers.
// The dirty property is used by the highlighter to determine
// which parts of the document have to be re-highlighted.
function insertPart(part){
var text = "\n";
share/endpoint/www/js/editor.js view on Meta::CPAN
return (caseFold ? line.toLowerCase() : line);
}
var topPos = {node: null, offset: 0};
if (from && typeof from == "object" && typeof from.character == "number") {
editor.checkLine(from.line);
var pos = {node: from.line, offset: from.character};
this.pos = {from: pos, to: pos};
}
else if (from) {
this.pos = {from: select.cursorPos(editor.container, true) || topPos,
to: select.cursorPos(editor.container, false) || topPos};
}
else {
this.pos = {from: topPos, to: topPos};
}
if (caseFold) string = string.toLowerCase();
// Create a matcher function based on the kind of string we have.
var target = string.split("\n");
this.matches = (target.length == 1) ?
// For one-line strings, searching can be done simply by calling
share/endpoint/www/js/editor.js view on Meta::CPAN
SearchCursor.prototype = {
findNext: function() {return this.find(false);},
findPrevious: function() {return this.find(true);},
find: function(reverse) {
if (!this.valid) return false;
var self = this, pos = reverse ? this.pos.from : this.pos.to,
node = pos.node, offset = pos.offset;
// Reset the cursor if the current line is no longer in the DOM tree.
if (node && !node.parentNode) {
node = null; offset = 0;
}
function savePosAndFail() {
var pos = {node: node, offset: offset};
self.pos = {from: pos, to: pos};
self.atOccurrence = false;
return false;
}
share/endpoint/www/js/editor.js view on Meta::CPAN
var focusEvent = addEventHandler(document, "focus", function() {
focusEvent();
setEditable();
}, true);
}
addEventHandler(document, "keydown", method(this, "keyDown"));
addEventHandler(document, "keypress", method(this, "keyPress"));
addEventHandler(document, "keyup", method(this, "keyUp"));
function cursorActivity() {self.cursorActivity(false);}
addEventHandler(internetExplorer ? document.body : window, "mouseup", cursorActivity);
addEventHandler(document.body, "cut", cursorActivity);
// workaround for a gecko bug [?] where going forward and then
// back again breaks designmode (no more cursor)
if (gecko)
addEventHandler(window, "pagehide", function(){self.unloaded = true;});
addEventHandler(document.body, "paste", function(event) {
cursorActivity();
var text = null;
try {
var clipboardData = event.clipboardData || window.clipboardData;
if (clipboardData) text = clipboardData.getData('Text');
}
catch(e) {}
if (text !== null) {
event.stop();
self.replaceSelection(text);
select.scrollToCursor(self.container);
share/endpoint/www/js/editor.js view on Meta::CPAN
accum.pop();
webkitLastLineHack(this.container);
return cleanText(accum.join(""));
},
checkLine: function(node) {
if (node === false || !(node == null || node.parentNode == this.container))
throw parent.CodeMirror.InvalidLineHandle;
},
cursorPosition: function(start) {
if (start == null) start = true;
var pos = select.cursorPos(this.container, start);
if (pos) return {line: pos.node, character: pos.offset};
else return {line: null, character: 0};
},
firstLine: function() {
return null;
},
lastLine: function() {
if (this.container.lastChild) return startOfLine(this.container.lastChild);
share/endpoint/www/js/editor.js view on Meta::CPAN
}
this.addDirtyNode(line);
this.scheduleHighlight();
},
// Retrieve the selected text.
selectedText: function() {
var h = this.history;
h.commit();
var start = select.cursorPos(this.container, true),
end = select.cursorPos(this.container, false);
if (!start || !end) return "";
if (start.node == end.node)
return h.textAfter(start.node).slice(start.offset, end.offset);
var text = [h.textAfter(start.node).slice(start.offset)];
for (var pos = h.nodeAfter(start.node); pos != end.node; pos = h.nodeAfter(pos))
text.push(h.textAfter(pos));
text.push(h.textAfter(end.node).slice(0, end.offset));
return cleanText(text.join("\n"));
},
// Replace the selection with another piece of text.
replaceSelection: function(text) {
this.history.commit();
var start = select.cursorPos(this.container, true),
end = select.cursorPos(this.container, false);
if (!start || !end) return;
end = this.replaceRange(start, end, text);
select.setCursorPos(this.container, end);
webkitLastLineHack(this.container);
},
cursorCoords: function(start) {
var sel = select.cursorPos(this.container, start);
if (!sel) return null;
var off = sel.offset, node = sel.node, self = this;
function measureFromNode(node, xOffset) {
var y = -(document.body.scrollTop || document.documentElement.scrollTop || 0),
x = -(document.body.scrollLeft || document.documentElement.scrollLeft || 0) + xOffset;
forEach([node, window.frameElement], function(n) {
while (n) {x += n.offsetLeft; y += n.offsetTop;n = n.offsetParent;}
});
return {x: x, y: y, yBot: y + node.offsetHeight};
}
share/endpoint/www/js/editor.js view on Meta::CPAN
if (this.pageUp()) event.stop();
}
else if (code == 34 && !event.shiftKey && !event.ctrlKey && !gecko) { // PgDn
if (this.pageDown()) event.stop();
}
else if ((code == 219 || code == 221) && event.ctrlKey && !event.altKey) { // [, ]
this.highlightParens(event.shiftKey, true);
event.stop();
}
else if (event.metaKey && !event.shiftKey && (code == 37 || code == 39)) { // Meta-left/right
var cursor = select.selectionTopNode(this.container);
if (cursor === false || !this.container.firstChild) return;
if (code == 37) select.focusAfterNode(startOfLine(cursor), this.container);
else {
var end = endOfLine(cursor, this.container);
select.focusAfterNode(end ? end.previousSibling : this.container.lastChild, this.container);
}
event.stop();
}
else if ((event.ctrlKey || event.metaKey) && !event.altKey) {
if ((event.shiftKey && code == 90) || code == 89) { // shift-Z, Y
select.scrollToNode(this.history.redo());
event.stop();
}
else if (code == 90 || (safari && code == 8)) { // Z, backspace
share/endpoint/www/js/editor.js view on Meta::CPAN
if ((this.frozen && (!this.keyFilter || this.keyFilter(event.keyCode || event.code, event))) ||
event.code == 13 || (event.code == 9 && this.options.tabMode != "default") ||
(event.code == 32 && event.shiftKey && this.options.tabMode == "default"))
event.stop();
else if (mac && (event.ctrlKey || event.metaKey) && event.character == "v") {
this.reroutePasteEvent();
}
else if (electric && electric.indexOf(event.character) != -1)
this.parent.setTimeout(function(){self.indentAtCursor(null);}, 0);
// Work around a bug where pressing backspace at the end of a
// line, or delete at the start, often causes the cursor to jump
// to the start of the line in Opera 10.60.
else if (brokenOpera) {
if (event.code == 8) { // backspace
var sel = select.selectionTopNode(this.container), self = this,
next = sel ? sel.nextSibling : this.container.firstChild;
if (sel !== false && next && isBR(next))
this.parent.setTimeout(function(){
if (select.selectionTopNode(self.container) == next)
select.focusAfterNode(next.previousSibling, self.container);
}, 20);
share/endpoint/www/js/editor.js view on Meta::CPAN
if (select.selectionTopNode(self.container) != sel)
select.focusAfterNode(sel, self.container);
}, 20);
}
}
}
// In 533.* WebKit versions, when the document is big, typing
// something at the end of a line causes the browser to do some
// kind of stupid heavy operation, creating delays of several
// seconds before the typed characters appear. This very crude
// hack inserts a temporary zero-width space after the cursor to
// make it not be at the end of the line.
else if (slowWebkit) {
var sel = select.selectionTopNode(this.container),
next = sel ? sel.nextSibling : this.container.firstChild;
// Doesn't work on empty lines, for some reason those always
// trigger the delay.
if (sel && next && isBR(next) && !isBR(sel)) {
var cheat = document.createTextNode("\u200b");
this.container.insertBefore(cheat, next);
this.parent.setTimeout(function() {
share/endpoint/www/js/editor.js view on Meta::CPAN
// the window.
if (webkit && !this.options.textWrapping)
setTimeout(function () {
var node = select.selectionTopNode(self.container, true);
if (node && node.nodeType == 3 && node.previousSibling && isBR(node.previousSibling)
&& node.nextSibling && isBR(node.nextSibling))
node.parentNode.replaceChild(document.createElement("BR"), node.previousSibling);
}, 50);
},
// Mark the node at the cursor dirty when a non-safe key is
// released.
keyUp: function(event) {
this.cursorActivity(isSafeKey(event.keyCode));
},
// Indent the line following a given <br>, or null for the first
// line. If given a <br> element, this must have been highlighted
// so that it has an indentation method. Returns the whitespace
// element that has been modified or created (if any).
indentLineAfter: function(start, direction) {
function whiteSpaceAfter(node) {
var ws = node ? node.nextSibling : self.container.firstChild;
if (!ws || !hasClass(ws, "whitespace")) return null;
share/endpoint/www/js/editor.js view on Meta::CPAN
// Otherwise, we have to add a new whitespace node.
else {
whiteSpace = makePartSpan(makeWhiteSpace(newIndent));
whiteSpace.className = "whitespace";
if (start) insertAfter(whiteSpace, start);
else this.container.insertBefore(whiteSpace, this.container.firstChild);
select.snapshotMove(firstText && (firstText.firstChild || firstText),
whiteSpace.firstChild, newIndent, false, true);
}
}
// Make sure cursor ends up after the whitespace
else if (whiteSpace) {
select.snapshotMove(whiteSpace.firstChild, whiteSpace.firstChild, newIndent, false);
}
if (indentDiff != 0) this.addDirtyNode(start);
},
// Re-highlight the selected part of the document.
highlightAtCursor: function() {
var pos = select.selectionTopNode(this.container, true);
var to = select.selectionTopNode(this.container, false);
if (pos === false || to === false) return false;
select.markSelection();
if (this.highlight(pos, endOfLine(to, this.container), true, 20) === false)
return false;
select.selectMarked();
return true;
},
// When tab is pressed with text selected, the whole selection is
// re-indented, when nothing is selected, the line with the cursor
// is re-indented.
handleTab: function(direction) {
if (this.options.tabMode == "spaces")
select.insertTabAtCursor();
else
this.reindentSelection(direction);
},
// Custom home behaviour that doesn't land the cursor in front of
// leading whitespace unless pressed twice.
home: function() {
var cur = select.selectionTopNode(this.container, true), start = cur;
if (cur === false || !(!cur || cur.isPart || isBR(cur)) || !this.container.firstChild)
return false;
while (cur && !isBR(cur)) cur = cur.previousSibling;
var next = cur ? cur.nextSibling : this.container.firstChild;
if (next && next != start && next.isPart && hasClass(next, "whitespace"))
select.focusAfterNode(next, this.container);
share/endpoint/www/js/editor.js view on Meta::CPAN
var cur = select.selectionTopNode(this.container, true);
if (cur === false) return false;
cur = endOfLine(cur, this.container);
if (!cur) return false;
select.focusAfterNode(cur.previousSibling, this.container);
select.scrollToCursor(this.container);
return true;
},
pageUp: function() {
var line = this.cursorPosition().line, scrollAmount = this.visibleLineCount();
if (line === false || scrollAmount === false) return false;
// Try to keep one line on the screen.
scrollAmount -= 2;
for (var i = 0; i < scrollAmount; i++) {
line = this.prevLine(line);
if (line === false) break;
}
if (i == 0) return false; // Already at first line
select.setCursorPos(this.container, {node: line, offset: 0});
select.scrollToCursor(this.container);
return true;
},
pageDown: function() {
var line = this.cursorPosition().line, scrollAmount = this.visibleLineCount();
if (line === false || scrollAmount === false) return false;
// Try to move to the last line of the current page.
scrollAmount -= 2;
for (var i = 0; i < scrollAmount; i++) {
var nextLine = this.nextLine(line);
if (nextLine === false) break;
line = nextLine;
}
if (i == 0) return false; // Already at last line
select.setCursorPos(this.container, {node: line, offset: 0});
share/endpoint/www/js/editor.js view on Meta::CPAN
return true;
},
// Delay (or initiate) the next paren highlight event.
scheduleParenHighlight: function() {
if (this.parenEvent) this.parent.clearTimeout(this.parenEvent);
var self = this;
this.parenEvent = this.parent.setTimeout(function(){self.highlightParens();}, 300);
},
// Take the token before the cursor. If it contains a character in
// '()[]{}', search for the matching paren/brace/bracket, and
// highlight them in green for a moment, or red if no proper match
// was found.
highlightParens: function(jump, fromKey) {
var self = this;
// give the relevant nodes a colour.
function highlight(node, ok) {
if (!node) return;
if (self.options.markParen) {
self.options.markParen(node, ok);
share/endpoint/www/js/editor.js view on Meta::CPAN
if (node.currentText) {
var match = node.currentText.match(/^[\s\u00a0]*([\(\)\[\]{}])[\s\u00a0]*$/);
return match && match[1];
}
}
// Determine the direction a paren is facing.
function forward(ch) {
return /[\(\[\{]/.test(ch);
}
var ch, cursor = select.selectionTopNode(this.container, true);
if (!cursor || !this.highlightAtCursor()) return;
cursor = select.selectionTopNode(this.container, true);
if (!(cursor && ((ch = paren(cursor)) || (cursor = cursor.nextSibling) && (ch = paren(cursor)))))
return;
// We only look for tokens with the same className.
var className = cursor.className, dir = forward(ch), match = matching[ch];
// Since parts of the document might not have been properly
// highlighted, and it is hard to know in advance which part we
// have to scan, we just try, and when we find dirty nodes we
// abort, parse them, and re-try.
function tryFindMatch() {
var stack = [], ch, ok = true;
for (var runner = cursor; runner; runner = dir ? runner.nextSibling : runner.previousSibling) {
if (runner.className == className && isSpan(runner) && (ch = paren(runner))) {
if (forward(ch) == dir)
stack.push(ch);
else if (!stack.length)
ok = false;
else if (stack.pop() != matching[ch])
ok = false;
if (!stack.length) break;
}
else if (runner.dirty || !isSpan(runner) && !isBR(runner)) {
share/endpoint/www/js/editor.js view on Meta::CPAN
while (true) {
var found = tryFindMatch();
if (found.status == "dirty") {
this.highlight(found.node, endOfLine(found.node));
// Needed because in some corner cases a highlight does not
// reach a node.
found.node.dirty = false;
continue;
}
else {
highlight(cursor, found.status);
highlight(found.node, found.status);
if (fromKey)
self.parent.setTimeout(function() {unhighlight(cursor); unhighlight(found.node);}, 500);
else
self.highlighted = [cursor, found.node];
if (jump && found.node)
select.focusAfterNode(found.node.previousSibling, this.container);
break;
}
}
},
// Adjust the amount of whitespace at the start of the line that
// the cursor is on so that it is indented properly.
indentAtCursor: function(direction) {
if (!this.container.firstChild) return;
// The line has to have up-to-date lexical information, so we
// highlight it first.
if (!this.highlightAtCursor()) return;
var cursor = select.selectionTopNode(this.container, false);
// If we couldn't determine the place of the cursor,
// there's nothing to indent.
if (cursor === false)
return;
select.markSelection();
this.indentLineAfter(startOfLine(cursor), direction);
select.selectMarked();
},
// Indent all lines whose start falls inside of the current
// selection.
indentRegion: function(start, end, direction) {
var current = (start = startOfLine(start)), before = start && startOfLine(start.previousSibling);
if (!isBR(end)) end = endOfLine(end, this.container);
this.addDirtyNode(start);
do {
var next = endOfLine(current, this.container);
if (current) this.highlight(before, next, true);
this.indentLineAfter(current, direction);
before = current;
current = next;
} while (current != end);
select.setCursorPos(this.container, {node: start, offset: 0}, {node: end, offset: 0});
},
// Find the node that the cursor is in, mark it as dirty, and make
// sure a highlight pass is scheduled.
cursorActivity: function(safe) {
// pagehide event hack above
if (this.unloaded) {
window.document.designMode = "off";
window.document.designMode = "on";
this.unloaded = false;
}
if (internetExplorer) {
this.container.createTextRange().execCommand("unlink");
clearTimeout(this.saveSelectionSnapshot);
var self = this;
this.saveSelectionSnapshot = setTimeout(function() {
var snapshot = select.getBookmark(self.container);
if (snapshot) self.selectionSnapshot = snapshot;
}, 200);
}
var activity = this.options.cursorActivity;
if (!safe || activity) {
var cursor = select.selectionTopNode(this.container, false);
if (cursor === false || !this.container.firstChild) return;
cursor = cursor || this.container.firstChild;
if (activity) activity(cursor);
if (!safe) {
this.scheduleHighlight();
this.addDirtyNode(cursor);
}
}
},
reparseBuffer: function() {
forEach(this.container.childNodes, function(node) {node.dirty = true;});
if (this.container.firstChild)
this.addDirtyNode(this.container.firstChild);
},
share/endpoint/www/js/editor.js view on Meta::CPAN
// next.
remove: function(){
container.removeChild(this.get());
this.current = null;
},
// Advance to the next part that is not empty, discarding empty
// parts.
getNonEmpty: function(){
var part = this.get();
// Allow empty nodes when they are alone on a line, needed
// for the FF cursor bug workaround (see select.js,
// insertNewlineAtCursor).
while (part && isSpan(part) && part.currentText == "") {
// Leave empty nodes that are alone on a line alone in
// Opera, since that browsers doesn't deal well with
// having 2 BRs in a row.
if (window.opera && surroundedByBRs(part)) {
this.next();
part = this.get();
}
else {
share/endpoint/www/js/mirrorframe.js view on Meta::CPAN
this.mirror = new CodeMirror(this.home, options);
}
MirrorFrame.prototype = {
search: function() {
var text = prompt("Enter search term:", "");
if (!text) return;
var first = true;
do {
var cursor = this.mirror.getSearchCursor(text, first);
first = false;
while (cursor.findNext()) {
cursor.select();
if (!confirm("Search again?"))
return;
}
} while (confirm("End of document reached. Start over?"));
},
replace: function() {
// This is a replace-all, but it is possible to implement a
// prompting replace.
var from = prompt("Enter search string:", ""), to;
if (from) to = prompt("What should it be replaced with?", "");
if (to == null) return;
var cursor = this.mirror.getSearchCursor(from, false);
while (cursor.findNext())
cursor.replace(to);
},
jump: function() {
var line = prompt("Jump to line:", "");
if (line && !isNaN(Number(line)))
this.mirror.jumpToLine(Number(line));
},
line: function() {
alert("The cursor is currently at line " + this.mirror.currentLine());
this.mirror.focus();
},
macro: function() {
var name = prompt("Name your constructor:", "");
if (name)
this.mirror.replaceSelection("function " + name + "() {\n \n}\n\n" + name + ".prototype = {\n \n};\n");
},
reindent: function() {
share/endpoint/www/js/parsejavascript.js view on Meta::CPAN
}
// Register a variable in the current scope.
function register(varname){
if (context){
mark("js-variabledef");
context.vars[varname] = true;
}
}
// Check whether a variable is defined in the current scope.
function inScope(varname){
var cursor = context;
while (cursor) {
if (cursor.vars[varname])
return true;
cursor = cursor.prev;
}
return false;
}
// Push a new lexical context of the given type.
function pushlex(type, info) {
var result = function(){
lexical = new JSLexical(indented, column, type, null, lexical, info)
};
result.lex = true;
share/endpoint/www/js/select.js view on Meta::CPAN
// Find the top-level node that contains the node before this one.
function topLevelNodeBefore(node, top) {
while (!node.previousSibling && node.parentNode != top)
node = node.parentNode;
return topLevelNodeAt(node.previousSibling, top);
}
var fourSpaces = "\u00a0\u00a0\u00a0\u00a0";
select.scrollToNode = function(node, cursor) {
if (!node) return;
var element = node, body = document.body,
html = document.documentElement,
atEnd = !element.nextSibling || !element.nextSibling.nextSibling
|| !element.nextSibling.nextSibling.nextSibling;
// In Opera (and recent Webkit versions), BR elements *always*
// have a offsetTop property of zero.
var compensateHack = 0;
while (element && !element.offsetTop) {
compensateHack++;
element = element.previousSibling;
}
// atEnd is another kludge for these browsers -- if the cursor is
// at the end of the document, and the node doesn't have an
// offset, just scroll to the end.
if (compensateHack == 0) atEnd = false;
// WebKit has a bad habit of (sometimes) happily returning bogus
// offsets when the document has just been changed. This seems to
// always be 5/5, so we don't use those.
if (webkit && element && element.offsetTop == 5 && element.offsetLeft == 5)
return;
share/endpoint/www/js/select.js view on Meta::CPAN
// Don't count X offset for <br> nodes
if (!isBR(pos))
x += pos.offsetLeft;
pos = pos.offsetParent;
}
var scroll_x = body.scrollLeft || html.scrollLeft || 0,
scroll_y = body.scrollTop || html.scrollTop || 0,
scroll = false, screen_width = window.innerWidth || html.clientWidth || 0;
if (cursor || width < screen_width) {
if (cursor) {
var off = select.offsetInNode(node), size = nodeText(node).length;
if (size) x += width * (off / size);
}
var screen_x = x - scroll_x;
if (screen_x < 0 || screen_x > screen_width) {
scroll_x = x;
scroll = true;
}
}
var screen_y = y - scroll_y;
share/endpoint/www/js/select.js view on Meta::CPAN
select.offsetInNode = function(node) {
var sel = document.selection;
if (!sel) return 0;
var range = sel.createRange(), range2 = range.duplicate();
try {range2.moveToElementText(node);} catch(e){return 0;}
range.setEndPoint("StartToStart", range2);
return range.text.length;
};
// Get the top-level node that one end of the cursor is inside or
// after. Note that this returns false for 'no cursor', and null
// for 'start of document'.
select.selectionTopNode = function(container, start) {
var selection = document.selection;
if (!selection) return false;
var range = selection.createRange(), range2 = range.duplicate();
range.collapse(start);
var around = range.parentElement();
if (around && isAncestor(container, around)) {
// Only use this node if the selection is not at its start.
share/endpoint/www/js/select.js view on Meta::CPAN
test2.moveToElementText(container);
} catch(exception) {
return null;
}
if (test1.compareEndPoints("StartToStart", test2) == 0)
return null;
}
return container.childNodes[start] || null;
};
// Place the cursor after this.start. This is only useful when
// manually moving the cursor instead of restoring it to its old
// position.
select.focusAfterNode = function(node, container) {
var range = document.body.createTextRange();
range.moveToElementText(node || container);
range.collapse(!node);
range.select();
};
select.somethingSelected = function() {
var sel = document.selection;
share/endpoint/www/js/select.js view on Meta::CPAN
// Used to normalize the effect of the enter key, since browsers
// do widely different things when pressing enter in designMode.
select.insertNewlineAtCursor = function() {
insertAtCursor("<br>");
};
select.insertTabAtCursor = function() {
insertAtCursor(fourSpaces);
};
// Get the BR node at the start of the line on which the cursor
// currently is, and the offset into the line. Returns null as
// node if cursor is on first line.
select.cursorPos = function(container, start) {
var selection = document.selection;
if (!selection) return null;
var topNode = select.selectionTopNode(container, start);
while (topNode && !isBR(topNode))
topNode = topNode.previousSibling;
var range = selection.createRange(), range2 = range.duplicate();
range.collapse(start);
if (topNode) {
share/endpoint/www/js/select.js view on Meta::CPAN
}
var range = rangeAt(from);
if (to && to != from)
range.setEndPoint("EndToEnd", rangeAt(to));
range.select();
}
// Some hacks for storing and re-storing the selection when the editor loses and regains focus.
select.getBookmark = function (container) {
var from = select.cursorPos(container, true), to = select.cursorPos(container, false);
if (from && to) return {from: from, to: to};
};
// Restore a stored selection.
select.setBookmark = function(container, mark) {
if (!mark) return;
select.setCursorPos(container, mark.from, mark.to);
};
}
// W3C model
else {
// Find the node right at the cursor, not one of its
// ancestors with a suitable offset. This goes down the DOM tree
// until a 'leaf' is reached (or is it *up* the DOM tree?).
function innerNode(node, offset) {
while (node.nodeType != 3 && !isBR(node)) {
var newNode = node.childNodes[offset] || node.nextSibling;
offset = 0;
while (!newNode && node.parentNode) {
node = node.parentNode;
newNode = node.nextSibling;
}
share/endpoint/www/js/select.js view on Meta::CPAN
selection.addRange(range);
}
function selectionRange() {
var selection = window.getSelection();
if (!selection || selection.rangeCount == 0)
return false;
else
return selection.getRangeAt(0);
}
// Finding the top-level node at the cursor in the W3C is, as you
// can see, quite an involved process.
select.selectionTopNode = function(container, start) {
var range = selectionRange();
if (!range) return false;
var node = start ? range.startContainer : range.endContainer;
var offset = start ? range.startOffset : range.endOffset;
// Work around (yet another) bug in Opera's selection model.
if (window.opera && !start && range.endContainer == container && range.endOffset == range.startOffset + 1 &&
container.childNodes[range.startOffset] && isBR(container.childNodes[range.startOffset]))
offset--;
// For text nodes, we look at the node itself if the cursor is
// inside, or at the node before it if the cursor is at the
// start.
if (node.nodeType == 3){
if (offset > 0)
return topLevelNodeAt(node, container);
else
return topLevelNodeBefore(node, container);
}
// Occasionally, browsers will return the HTML node as
// selection. If the offset is 0, we take the start of the frame
// ('after null'), otherwise, we take the last node.
else if (node.nodeName.toUpperCase() == "HTML") {
return (offset == 1 ? null : container.lastChild);
}
// If the given node is our 'container', we just look up the
// correct node by using the offset.
else if (node == container) {
return (offset == 0) ? null : node.childNodes[offset - 1];
}
// In any other case, we have a regular node. If the cursor is
// at the end of the node, we use the node itself, if it is at
// the start, we use the node before it, and in any other
// case, we look up the child before the cursor and use that.
else {
if (offset == node.childNodes.length)
return topLevelNodeAt(node, container);
else if (offset == 0)
return topLevelNodeBefore(node, container);
else
return topLevelNodeAt(node.childNodes[offset - 1], container);
}
};
select.focusAfterNode = function(node, container) {
var range = document.createRange();
range.setStartBefore(container.firstChild || container);
// In Opera, setting the end of a range at the end of a line
// (before a BR) will cause the cursor to appear on the next
// line, so we set the end inside of the start node when
// possible.
if (node && !node.firstChild)
range.setEndAfter(node);
else if (node)
range.setEnd(node, node.childNodes.length);
else
range.setEndBefore(container.firstChild || container);
range.collapse(false);
selectRange(range);
share/endpoint/www/js/select.js view on Meta::CPAN
}
select.insertNewlineAtCursor = function() {
select.insertNodeAtCursor(document.createElement("BR"));
};
select.insertTabAtCursor = function() {
select.insertNodeAtCursor(document.createTextNode(fourSpaces));
};
select.cursorPos = function(container, start) {
var range = selectionRange();
if (!range) return;
var topNode = select.selectionTopNode(container, start);
while (topNode && !isBR(topNode))
topNode = topNode.previousSibling;
range = range.cloneRange();
range.collapse(start);
if (topNode)
share/endpoint/www/js/undo.js view on Meta::CPAN
// (The this.before(end) is a hack -- FF sometimes removes
// properties from BR nodes, in which case the best we can hope
// for is to not break.)
}
return shadows;
},
// Update the DOM tree to contain the lines specified in a given
// chain, link this chain into the DOM nodes.
applyChain: function(chain) {
// Some attempt is made to prevent the cursor from jumping
// randomly when an undo or redo happens. It still behaves a bit
// strange sometimes.
var cursor = select.cursorPos(this.container, false), self = this;
// Remove all nodes in the DOM tree between from and to (null for
// start/end of container).
function removeRange(from, to) {
var pos = from ? from.nextSibling : self.container.firstChild;
while (pos != to) {
var temp = pos.nextSibling;
removeElement(pos);
pos = temp;
}
share/endpoint/www/js/undo.js view on Meta::CPAN
for (var i = 0; i < chain.length; i++) {
var line = chain[i];
// The start and end of the space are already correct, but BR
// tags inside it have to be put back.
if (i > 0)
self.container.insertBefore(line.from, end);
// Add the text.
var node = makePartSpan(fixSpaces(line.text));
self.container.insertBefore(node, end);
// See if the cursor was on this line. Put it back, adjusting
// for changed line length, if it was.
if (cursor && cursor.node == line.from) {
var cursordiff = 0;
var prev = this.after(line.from);
if (prev && i == chain.length - 1) {
// Only adjust if the cursor is after the unchanged part of
// the line.
for (var match = 0; match < cursor.offset &&
line.text.charAt(match) == prev.text.charAt(match); match++){}
if (cursor.offset > match)
cursordiff = line.text.length - prev.text.length;
}
select.setCursorPos(this.container, {node: line.from, offset: Math.max(0, cursor.offset + cursordiff)});
}
// Cursor was in removed line, this is last new line.
else if (cursor && (i == chain.length - 1) && cursor.node && cursor.node.parentNode != this.container) {
select.setCursorPos(this.container, {node: line.from, offset: line.text.length});
}
}
// Anchor the chain in the DOM tree.
this.linkChain(chain);
return start;
}
};