jquery-ui实现一个多tab标签页可拖动编辑器记事本效果代码
代码语言:html
所属分类:其他
代码描述:jquery-ui实现一个多tab标签页可拖动编辑器效果代码
代码标签: jquery-ui tab 标签页 编辑器 记事本 拖动
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
@font-face {
font-family: 'icomoon';
src:url('data:application/font-woff;base64,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') format('woff'),
url('') format('truetype'),
url('') format('svg');
font-weight: normal;
font-style: normal;
}
[class^="icon-"], [class*=" icon-"] {
font-family: 'icomoon';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
/* Better Font Rendering =========== */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-paragraph-left:before {
content: "\e600";
}
.icon-paragraph-center:before {
content: "\e601";
}
.icon-paragraph-right:before {
content: "\e602";
}
.icon-bold:before {
content: "\e603";
}
.icon-underline:before {
content: "\e604";
}
.icon-italic:before {
content: "\e605";
}
.icon-plus:before {
content: "\e606";
}
.icon-minus:before {
content: "\e607";
}
.icon-quill:before {
content: "\e608";
}
@import url(https://fonts.googleapis.com/css?family=Telex);
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
body {
background: #5deaba;
}
.launch {
font-family: "Telex", sans-serif;
text-decoration: none;
width: 240px;
height: 60px;
display: block;
text-align: center;
line-height: 38px;
border-radius: 3px;
font-size: 60px;
color: #fff;
position: absolute;
left: 50%;
top: 50%;
margin: -30px 0 0 -120px;
display: none;
}
.texteditor {
width: 550px;
height: 450px;
position: absolute;
left: 50%;
top: 50%;
background: #fff;
margin: -205px 0 0 -275px;
border-radius: 0 0 10px 10px;
box-shadow: 0px -12px 200px #20b080;
}
.texteditor .ops {
height: 288px;
width: 50px;
background: #ebebeb;
position: absolute;
right: 0px;
border-radius: 0 10px 10px 0;
z-index: 1;
display: none;
}
.texteditor .ops ul {
list-style: none;
margin: 0;
padding: 0;
}
.texteditor .ops ul li {
text-align: center;
padding: 10px 0;
}
.texteditor .ops ul li:first-child {
border-radius: 0 10px 0 0;
}
.texteditor .ops ul li:last-child {
border-radius: 0 0 10px 0;
}
.texteditor .ops ul li:hover {
background: #31d687;
}
.texteditor .ops ul li:hover a {
color: #fff;
}
.texteditor .ops ul li a {
text-decoration: none;
color: grey;
display: block;
}
.texteditor .textareawrap .fontsize {
background: #5deaba;
position: absolute;
z-index: 400;
bottom: 5px;
left: 5px;
padding: 5px 10px;
font-family: "Telex", sans-serif;
color: #fff;
font-size: 16px;
border-radius: 0 0 0 5px;
display: none;
}
.texteditor .textareawrap .textarea {
display: none;
margin: 0;
padding: 10px;
width: 100%;
height: 100%;
position: absolute;
border: 0;
outline: none;
resize: none;
overflow: auto;
border-radius: 0 0 10px 10px;
font-family: "Telex", sans-serif;
font-size: 13px;
color: #666;
background: #fff;
z-index: 2;
}
.texteditor .top {
font-family: "Telex", sans-serif;
position: absolute;
height: 45px;
background: #ebebeb;
top: -45px;
width: 100%;
border-radius: 10px 10px 0 0;
border-bottom: 1px solid #bababa;
cursor: move;
overflow: hidden;
}
.texteditor .top .icon-quill {
font-size: 25px;
float: right;
margin: 0 10px 0 0;
color: grey;
text-decoration: none;
}
.texteditor .top .icon-quill:hover {
color: #31d687;
}
.texteditor ul.controls {
padding: 0;
margin: 16px 0 0 15px;
list-style: none;
float: left;
width: 65px;
}
.texteditor ul.controls li {
width: 15px;
height: 15px;
float: left;
margin: 0 4%;
border-radius: 50%;
cursor: pointer;
}
.texteditor ul.controls li:after {
content: "";
background: linear-gradient(225deg, #ffffff 50%, transparent 50%);
width: 15px;
height: 15px;
position: absolute;
z-index: 2;
border-radius: 50%;
opacity: 0.4;
}
.texteditor ul.controls .close {
background: #e57069;
}
.texteditor ul.controls .min {
background: #f5ce56;
}
.texteditor ul.controls .expand {
background: #31d687;
}
.texteditor ul.tabs {
margin: 9px 0 0 100px;
padding: 0;
list-style: none;
}
.texteditor ul.tabs .addtab {
font-size: 22px;
z-index: 305;
color: grey;
position: relative;
cursor: pointer;
float: left;
margin: 0 0 0 5px;
}
.texteditor ul.tabs .addtab:hover {
color: #31d687;
}
.texteditor ul.tabs li {
float: left;
width: auto;
margin: 0 -5px;
padding: 0 15px;
border-bottom: 35px solid #dad8d8;
border-right: 20px solid transparent;
border-left: 20px solid transparent;
height: 0;
line-height: 37px;
position: relative;
z-index: 2;
cursor: pointer;
}
.texteditor ul.tabs li span {
position: absolute;
top: -12px;
left: 2px;
display: none;
width: 17px;
height: 17px;
border-radius: 50%;
top: -5px;
left: -7px;
text-align: center;
line-height: 16px;
background: #e57069;
font-size: 20px;
z-index: 3;
}
.texteditor ul.tabs li span:after {
content: "";
background: linear-gradient(225deg, #ffffff 50%, transparent 50%);
width: 15px;
height: 15px;
position: absolute;
z-index: 2;
border-radius: 50%;
opacity: 0.2;
left: 2px;
}
.texteditor ul.tabs li a {
text-decoration: none;
color: #fff;
}
.ui-resizable-e {
right: 0;
position: absolute;
width: 5px;
height: 100%;
}
.ui-resizable-s {
bottom: 0;
height: 5px;
width: 100%;
position: absolute;
}
.ui-icon-gripsmall-diagonal-se {
z-index: 90;
bottom: 0;
right: 0;
position: absolute;
width: 10px;
height: 10px;
}
.ui-resizable-s:hover {
cursor: ns-resize;
}
.ui-resizable-e:hover {
cursor: ew-resize;
}
.ui-icon-gripsmall-diagonal-se:hover {
cursor: nwse-resize;
}
.active {
border-bottom-color: #bababa !important;
z-index: 300 !important;
}
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
.underline {
text-decoration: underline;
}
.leftalign {
text-align: left;
display: inline;
}
.rightalign {
text-align: right;
display: block;
}
.centeralign {
text-align: center;
display: block;
}
</style>
</head>
<body>
<a href="#" class="launch"> LAUNCH </a>
<div class="texteditor">
<div class="top">
<ul class="controls">
<li class="close">
<a href="#"></a>
</li>
<li class="min">
<a href="#"></a>
</li>
<li class="expand">
<a href="#"></a>
</li>
</ul>
<ul class="tabs">
<span class="tabwrap">
</span>
</ul>
<a href="#" class="icon-quill"></a>
</div>
<div class="textareawrap">
<span class="fontsize"></span>
</div>
<aside class="ops">
<ul>
<li>
<a href="#" class="icon-bold"></a>
</li>
<li>
<a class="icon-underline" href="#"></a>
</li>
<li>
<a class="icon-italic" href="#"></a>
</li>
<li>
<a class="icon-paragraph-left" href="#"></a>
</li>
<li>
<a class="icon-paragraph-right" href="#"></a>
</li>
<li>
<a class="icon-paragraph-center" href="#"></a>
</li>
<li>
<a class="icon-plus" href="#"></a>
</li>
<li>
<a class="icon-minus" href="#"></a>
</li>
</ul>
</aside>
</div>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jquery.2.11.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/jquery-ui-1.10.3.min.js"></script>
<script>
(function (factory, root) {
if (typeof define == "function" && define.amd) {
// AMD. Register as an anonymous module.
define(factory);
} else if (typeof module != "undefined" && typeof exports == "object") {
// Node/CommonJS style
module.exports = factory();
} else {
// No AMD or CommonJS support so we place Rangy in (probably) the global variable
root.rangy = factory();
}
})(function () {
var OBJECT = "object",FUNCTION = "function",UNDEFINED = "undefined";
// Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START
// are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113.
var domRangeProperties = ["startContainer", "startOffset", "endContainer", "endOffset", "collapsed",
"commonAncestorContainer"];
// Minimal set of methods required for DOM Level 2 Range compliance
var domRangeMethods = ["setStart", "setStartBefore", "setStartAfter", "setEnd", "setEndBefore",
"setEndAfter", "collapse", "selectNode", "selectNodeContents", "compareBoundaryPoints", "deleteContents",
"extractContents", "cloneContents", "insertNode", "surroundContents", "cloneRange", "toString", "detach"];
var textRangeProperties = ["boundingHeight", "boundingLeft", "boundingTop", "boundingWidth", "htmlText", "text"];
// Subset of TextRange's full set of methods that we're interested in
var textRangeMethods = ["collapse", "compareEndPoints", "duplicate", "moveToElementText", "parentElement", "select",
"setEndPoint", "getBoundingClientRect"];
/*----------------------------------------------------------------------------------------------------------------*/
// Trio of functions taken from Peter Michaux's article:
// http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting
function isHostMethod(o, p) {
var t = typeof o[p];
return t == FUNCTION || !!(t == OBJECT && o[p]) || t == "unknown";
}
function isHostObject(o, p) {
return !!(typeof o[p] == OBJECT && o[p]);
}
function isHostProperty(o, p) {
return typeof o[p] != UNDEFINED;
}
// Creates a convenience function to save verbose repeated calls to tests functions
function createMultiplePropertyTest(testFunc) {
return function (o, props) {
var i = props.length;
while (i--) {if (window.CP.shouldStopExecution(0)) break;
if (!testFunc(o, props[i])) {
return false;
}
}window.CP.exitedLoop(0);
return true;
};
}
// Next trio of functions are a convenience to save verbose repeated calls to previous two functions
var areHostMethods = createMultiplePropertyTest(isHostMethod);
var areHostObjects = createMultiplePropertyTest(isHostObject);
var areHostProperties = createMultiplePropertyTest(isHostProperty);
function isTextRange(range) {
return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);
}
function getBody(doc) {
return isHostObject(doc, "body") ? doc.body : doc.getElementsByTagName("body")[0];
}
var forEach = [].forEach ?
function (arr, func) {
arr.forEach(func);
} :
function (arr, func) {
for (var i = 0, len = arr.length; i < len; ++i) {if (window.CP.shouldStopExecution(1)) break;
func(arr[i], i);
}window.CP.exitedLoop(1);
};
var modules = {};
var isBrowser = typeof window != UNDEFINED && typeof document != UNDEFINED;
var util = {
isHostMethod: isHostMethod,
isHostObject: isHostObject,
isHostProperty: isHostProperty,
areHostMethods: areHostMethods,
areHostObjects: areHostObjects,
areHostProperties: areHostProperties,
isTextRange: isTextRange,
getBody: getBody,
forEach: forEach };
var api = {
version: "1.3.1-dev",
initialized: false,
isBrowser: isBrowser,
supported: true,
util: util,
features: {},
modules: modules,
config: {
alertOnFail: false,
alertOnWarn: false,
preferTextRange: false,
autoInitialize: typeof rangyAutoInitialize == UNDEFINED ? true : rangyAutoInitialize } };
function consoleLog(msg) {
if (typeof console != UNDEFINED && isHostMethod(console, "log")) {
console.log(msg);
}
}
function alertOrLog(msg, shouldAlert) {
if (isBrowser && shouldAlert) {
alert(msg);
} else {
consoleLog(msg);
}
}
function fail(reason) {
api.initialized = true;
api.supported = false;
alertOrLog("Rangy is not supported in this environment. Reason: " + reason, api.config.alertOnFail);
}
api.fail = fail;
function warn(msg) {
alertOrLog("Rangy warning: " + msg, api.config.alertOnWarn);
}
api.warn = warn;
// Add utility extend() method
var extend;
if ({}.hasOwnProperty) {
util.extend = extend = function (obj, props, deep) {
var o, p;
for (var i in props) {
if (props.hasOwnProperty(i)) {
o = obj[i];
p = props[i];
if (deep && o !== null && typeof o == "object" && p !== null && typeof p == "object") {
extend(o, p, true);
}
obj[i] = p;
}
}
// Special case for toString, which does not show up in for...in loops in IE <= 8
if (props.hasOwnProperty("toString")) {
obj.toString = props.toString;
}
return obj;
};
util.createOptions = function (optionsParam, defaults) {
var options = {};
extend(options, defaults);
if (optionsParam) {
extend(options, optionsParam);
}
return options;
};
} else {
fail("hasOwnProperty not supported");
}
// Test whether we're in a browser and bail out if not
if (!isBrowser) {
fail("Rangy can only run in a browser");
}
// Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not
(function () {
var toArray;
if (isBrowser) {
var el = document.createElement("div");
el.appendChild(document.createElement("span"));
var slice = [].slice;
try {
if (slice.call(el.childNodes, 0)[0].nodeType == 1) {
toArray = function (arrayLike) {
return slice.call(arrayLike, 0);
};
}
} catch (e) {}
}
if (!toArray) {
toArray = function (arrayLike) {
var arr = [];
for (var i = 0, len = arrayLike.length; i < len; ++i) {if (window.CP.shouldStopExecution(2)) break;
arr[i] = arrayLike[i];
}window.CP.exitedLoop(2);
return arr;
};
}
util.toArray = toArray;
})();
// Very simple event handler wrapper function that doesn't attempt to solve issues such as "this" handling or
// normalization of event properties
var addListener;
if (isBrowser) {
if (isHostMethod(document, "addEventListener")) {
addListener = function (obj, eventType, listener) {
obj.addEventListener(eventType, listener, false);
};
} else if (isHostMethod(document, "attachEvent")) {
addListener = function (obj, eventType, listener) {
obj.attachEvent("on" + eventType, listener);
};
} else {
fail("Document does not have required addEventListener or attachEvent method");
}
util.addListener = addListener;
}
var initListeners = [];
function getErrorDesc(ex) {
return ex.message || ex.description || String(ex);
}
// Initialization
function init() {
if (!isBrowser || api.initialized) {
return;
}
var testRange;
var implementsDomRange = false,implementsTextRange = false;
// First, perform basic feature tests
if (isHostMethod(document, "createRange")) {
testRange = document.createRange();
if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {
implementsDomRange = true;
}
}
var body = getBody(document);
if (!body || body.nodeName.toLowerCase() != "body") {
fail("No body element found");
return;
}
if (body && isHostMethod(body, "createTextRange")) {
testRange = body.createTextRange();
if (isTextRange(testRange)) {
implementsTextRange = true;
}
}
if (!implementsDomRange && !implementsTextRange) {
fail("Neither Range nor TextRange are available");
return;
}
api.initialized = true;
api.features = {
implementsDomRange: implementsDomRange,
implementsTextRange: implementsTextRange };
// Initialize modules
var module, errorMessage;
for (var moduleName in modules) {
if ((module = modules[moduleName]) instanceof Module) {
module.init(module, api);
}
}
// Call init listeners
for (var i = 0, len = initListeners.length; i < len; ++i) {if (window.CP.shouldStopExecution(3)) break;
try {
initListeners[i](api);
} catch (ex) {
errorMessage = "Rangy init listener threw an exception. Continuing. Detail: " + getErrorDesc(ex);
consoleLog(errorMessage);
}
}window.CP.exitedLoop(3);
}
function deprecationNotice(deprecated, replacement, module) {
if (module) {
deprecated += " in module " + module.name;
}
api.warn("DEPRECATED: " + deprecated + " is deprecated. Please use " +
replacement + " instead.");
}
function createAliasForDeprecatedMethod(owner, deprecated, replacement, module) {
owner[deprecated] = function () {
deprecationNotice(deprecated, replacement, module);
return owner[replacement].apply(owner, util.toArray(arguments));
};
}
util.deprecationNotice = deprecationNotice;
util.createAliasForDeprecatedMethod = createAliasForDeprecatedMethod;
// Allow external scripts to initialize this library in case it's loaded after the document has loaded
api.init = init;
// Execute listener immediately if already initialized
api.addInitListener = function (listener) {
if (api.initialized) {
listener(api);
} else {
initListeners.push(listener);
}
};
var shimListeners = [];
api.addShimListener = function (listener) {
shimListeners.push(listener);
};
function shim(win) {
win = win || window;
init();
// Notify listeners
for (var i = 0, len = shimListeners.length; i < len; ++i) {if (window.CP.shouldStopExecution(4)) break;
shimListeners[i](win);
}window.CP.exitedLoop(4);
}
if (isBrowser) {
api.shim = api.createMissingNativeApi = shim;
createAliasForDeprecatedMethod(api, "createMissingNativeApi", "shim");
}
function Module(name, dependencies, initializer) {
this.name = name;
this.dependencies = dependencies;
this.initialized = false;
this.supported = false;
this.initializer = initializer;
}
Module.prototype = {
init: function () {
var requiredModuleNames = this.dependencies || [];
for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {if (window.CP.shouldStopExecution(5)) break;
moduleName = requiredModuleNames[i];
requiredModule = modules[moduleName];
if (!requiredModule || !(requiredModule instanceof Module)) {
throw new Error("required module '" + moduleName + "' not found");
}
requiredModule.init();
if (!requiredModule.supported) {
throw new Error("required module '" + moduleName + "' not supported");
}
}
// Now run initializer
window.CP.exitedLoop(5);this.initializer(this);
},
fail: function (reason) {
this.initialized = true;
this.supported = false;
throw new Error(reason);
},
warn: function (msg) {
api.warn("Module " + this.name + ": " + msg);
},
deprecationNotice: function (deprecated, replacement) {
api.warn("DEPRECATED: " + deprecated + " in module " + this.name + " is deprecated. Please use " +
replacement + " instead");
},
createError: function (msg) {
return new Error("Error in Rangy " + this.name + " module: " + msg);
} };
function createModule(name, dependencies, initFunc) {
var newModule = new Module(name, dependencies, function (module) {
if (!module.initialized) {
module.initialized = true;
try {
initFunc(api, module);
module.supported = true;
} catch (ex) {
var errorMessage = "Module '" + name + "' failed to load: " + getErrorDesc(ex);
consoleLog(errorMessage);
if (ex.stack) {
consoleLog(ex.stack);
}
}
}
});
modules[name] = newModule;
return newModule;
}
api.createModule = function (name) {
// Allow 2 or 3 arguments (second argument is an optional array of dependencies)
var initFunc, dependencies;
if (arguments.length == 2) {
initFunc = arguments[1];
dependencies = [];
} else {
initFunc = arguments[2];
dependencies = arguments[1];
}
var module = createModule(name, dependencies, initFunc);
// Initialize the module immediately if the core is already initialized
if (api.initialized && api.supported) {
module.init();
}
};
api.createCoreModule = function (name, dependencies, initFunc) {
createModule(name, dependencies, initFunc);
};
/*----------------------------------------------------------------------------------------------------------------*/
// Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately
function RangePrototype() {}
api.RangePrototype = RangePrototype;
api.rangePrototype = new RangePrototype();
function SelectionPrototype() {}
api.selectionPrototype = new SelectionPrototype();
/*----------------------------------------------------------------------------------------------------------------*/
// DOM utility methods used by Rangy
api.createCoreModule("DomUtil", [], function (api, module) {
var UNDEF = "undefined";
var util = api.util;
var getBody = util.getBody;
// Perform feature tests
if (!util.areHostMethods(document, ["createDocumentFragment", "createElement", "createTextNode"])) {
module.fail("document missing a Node creation method");
}
if (!util.isHostMethod(document, "getElementsByTagName")) {
module.fail("document missing getElementsByTagName method");
}
var el = document.createElement("div");
if (!util.areHostMethods(el, ["insertBefore", "appendChild", "cloneNode"] ||
!util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]))) {
module.fail("Incomplete Element implementation");
}
// innerHTML is required for Range's createContextualFragment method
if (!util.isHostProperty(el, "innerHTML")) {
module.fail("Element is missing innerHTML property");
}
var textNode = document.createTextNode("test");
if (!util.areHostMethods(textNode, ["splitText", "deleteData", "insertData", "appendData", "cloneNode"] ||
!util.areHostObjects(el, ["previousSibling", "nextSibling", "childNodes", "parentNode"]) ||
!util.areHostProperties(textNode, ["data"]))) {
module.fail("Incomplete Text Node implementation");
}
/*----------------------------------------------------------------------------------------------------------------*/
// Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been
// able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that
// contains just the document as a single element and the value searched for is the document.
var arrayContains = /*Array.prototype.indexOf ?
function(arr, val) {
return arr.indexOf(val) > -1;
}:*/
function (arr, val) {
var i = arr.length;
while (i--) {if (window.CP.shouldStopExecution(6)) break;
if (arr[i] === val) {
return true;
}
}window.CP.exitedLoop(6);
return false;
};
// Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI
function isHtmlNamespace(node) {
var ns;
return typeof node.namespaceURI == UNDEF || (ns = node.namespaceURI) === null || ns == "http://www.w3.org/1999/xhtml";
}
function parentElement(node) {
var parent = node.parentNode;
return parent.nodeType == 1 ? parent : null;
}
function getNodeIndex(node) {
var i = 0;
while (node = node.previousSibling) {if (window.CP.shouldStopExecution(7)) break;
++i;
}window.CP.exitedLoop(7);
return i;
}
function getNodeLength(node) {
switch (node.nodeType) {
case 7:
case 10:
return 0;
case 3:
case 8:
return node.length;
default:
return node.childNodes.length;}
}
function getCommonAncestor(node1, node2) {
var ancestors = [],n;
for (n = node1; n; n = n.parentNode) {if (window.CP.shouldStopExecution(8)) break;
ancestors.push(n);
}window.CP.exitedLoop(8);
for (n = node2; n; n = n.parentNode) {if (window.CP.shouldStopExecution(9)) break;
if (arrayContains(ancestors, n)) {
return n;
}
}window.CP.exitedLoop(9);
return null;
}
function isAncestorOf(ancestor, descendant, selfIsAncestor) {
var n = selfIsAncestor ? descendant : descendant.parentNode;
while (n) {if (window.CP.shouldStopExecution(10)) break;
if (n === ancestor) {
return true;
} else {
n = n.parentNode;
}
}window.CP.exitedLoop(10);
return false;
}
function isOrIsAncestorOf(ancestor, descendant) {
return isAncestorOf(ancestor, descendant, true);
}
function getClosestAncestorIn(node, ancestor, selfIsAncestor) {
var p,n = selfIsAncestor ? node : node.parentNode;
while (n) {if (window.CP.shouldStopExecution(11)) break;
p = n.parentNode;
if (p === ancestor) {
return n;
}
n = p;
}window.CP.exitedLoop(11);
return null;
}
function isCharacterDataNode(node) {
var t = node.nodeType;
return t == 3 || t == 4 || t == 8; // Text, CDataSection or Comment
}
function isTextOrCommentNode(node) {
if (!node) {
return false;
}
var t = node.nodeType;
return t == 3 || t == 8; // Text or Comment
}
function insertAfter(node, precedingNode) {
var nextNode = precedingNode.nextSibling,parent = precedingNode.parentNode;
if (nextNode) {
parent.insertBefore(node, nextNode);
} else {
parent.appendChild(node);
}
return node;
}
// Note that we cannot use splitText() because it is bugridden in IE 9.
function splitDataNode(node, index, positionsToPreserve) {
var newNode = node.cloneNode(false);
newNode.deleteData(0, index);
node.deleteData(index, node.length - index);
insertAfter(newNode, node);
// Preserve positions
if (positionsToPreserve) {
for (var i = 0, position; position = positionsToPreserve[i++];) {if (window.CP.shouldStopExecution(12)) break;
// Handle case where position was inside the portion of node after the split point
if (position.node == node && position.offset > index) {
position.node = newNode;
position.offset -= index;
}
// Handle the case where the position is a node offset within node's parent
else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) {
++position.offset;
}
}window.CP.exitedLoop(12);
}
return newNode;
}
function getDocument(node) {
if (node.nodeType == 9) {
return node;
} else if (typeof node.ownerDocument != UNDEF) {
return node.ownerDocument;
} else if (typeof node.document != UNDEF) {
return node.document;
} else if (node.parentNode) {
return getDocument(node.parentNode);
} else {
throw module.createError("getDocument: no document found for node");
}
}
function getWindow(node) {
var doc = getDocument(node);
if (typeof doc.defaultView != UNDEF) {
return doc.defaultView;
} else if (typeof doc.parentWindow != UNDEF) {
return doc.parentWindow;
} else {
throw module.createError("Cannot get a window object for node");
}
}
function getIframeDocument(iframeEl) {
if (typeof iframeEl.contentDocument != UNDEF) {
return iframeEl.contentDocument;
} else if (typeof iframeEl.contentWindow != UNDEF) {
return iframeEl.contentWindow.document;
} else {
throw module.createError("getIframeDocument: No Document object found for iframe element");
}
}
function getIframeWindow(iframeEl) {
if (typeof iframeEl.contentWindow != UNDEF) {
return iframeEl.contentWindow;
} else if (typeof iframeEl.contentDocument != UNDEF) {
return iframeEl.contentDocument.defaultView;
} else {
throw module.createError("getIframeWindow: No Window object found for iframe element");
}
}
// This looks bad. Is it worth it?
function isWindow(obj) {
return obj && util.isHostMethod(obj, "setTimeout") && util.isHostObject(obj, "document");
}
function getContentDocument(obj, module, methodName) {
va.........完整代码请登录后点击上方下载按钮下载查看
网友评论0