node.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. function _get(val) {
  2. return K(val)[0];
  3. }
  4. function _getDoc(node) {
  5. if (!node) {
  6. return document;
  7. }
  8. return node.ownerDocument || node.document || node;
  9. }
  10. function _getWin(node) {
  11. if (!node) {
  12. return window;
  13. }
  14. var doc = _getDoc(node);
  15. return doc.parentWindow || doc.defaultView;
  16. }
  17. function _setHtml(el, html) {
  18. if (el.nodeType != 1) {
  19. return;
  20. }
  21. var doc = _getDoc(el);
  22. try {
  23. el.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + html;
  24. var temp = doc.getElementById('__kindeditor_temp_tag__');
  25. temp.parentNode.removeChild(temp);
  26. } catch(e) {
  27. // bugfix: 在IE上innerHTML有时候报错
  28. K(el).empty();
  29. K('@' + html, doc).each(function() {
  30. el.appendChild(this);
  31. });
  32. }
  33. }
  34. function _hasClass(el, cls) {
  35. return _inString(cls, el.className, ' ');
  36. }
  37. function _setAttr(el, key, val) {
  38. if (_IE && _V < 8 && key.toLowerCase() == 'class') {
  39. key = 'className';
  40. }
  41. el.setAttribute(key, '' + val);
  42. }
  43. function _removeAttr(el, key) {
  44. if (_IE && _V < 8 && key.toLowerCase() == 'class') {
  45. key = 'className';
  46. }
  47. _setAttr(el, key, '');
  48. el.removeAttribute(key);
  49. }
  50. function _getNodeName(node) {
  51. if (!node || !node.nodeName) {
  52. return '';
  53. }
  54. return node.nodeName.toLowerCase();
  55. }
  56. function _computedCss(el, key) {
  57. var self = this, win = _getWin(el), camelKey = _toCamel(key), val = '';
  58. if (win.getComputedStyle) {
  59. var style = win.getComputedStyle(el, null);
  60. val = style[camelKey] || style.getPropertyValue(key) || el.style[camelKey];
  61. } else if (el.currentStyle) {
  62. val = el.currentStyle[camelKey] || el.style[camelKey];
  63. }
  64. return val;
  65. }
  66. function _hasVal(node) {
  67. return !!_VALUE_TAG_MAP[_getNodeName(node)];
  68. }
  69. function _docElement(doc) {
  70. doc = doc || document;
  71. return _QUIRKS ? doc.body : doc.documentElement;
  72. }
  73. function _docHeight(doc) {
  74. var el = _docElement(doc);
  75. return Math.max(el.scrollHeight, el.clientHeight);
  76. }
  77. function _docWidth(doc) {
  78. var el = _docElement(doc);
  79. return Math.max(el.scrollWidth, el.clientWidth);
  80. }
  81. function _getScrollPos(doc) {
  82. doc = doc || document;
  83. var x, y;
  84. if (_IE || _NEWIE || _OPERA) {
  85. x = _docElement(doc).scrollLeft;
  86. y = _docElement(doc).scrollTop;
  87. } else {
  88. x = _getWin(doc).scrollX;
  89. y = _getWin(doc).scrollY;
  90. }
  91. return {x : x, y : y};
  92. }
  93. // create KNode class
  94. function KNode(node) {
  95. this.init(node);
  96. }
  97. _extend(KNode, {
  98. init : function(node) {
  99. var self = this;
  100. node = _isArray(node) ? node : [node];
  101. var length = 0;
  102. for (var i = 0, len = node.length; i < len; i++) {
  103. if (node[i]) {
  104. self[i] = node[i].constructor === KNode ? node[i][0] : node[i];
  105. length++;
  106. }
  107. }
  108. self.length = length;
  109. self.doc = _getDoc(self[0]);
  110. self.name = _getNodeName(self[0]);
  111. self.type = self.length > 0 ? self[0].nodeType : null;
  112. self.win = _getWin(self[0]);
  113. },
  114. each : function(fn) {
  115. var self = this;
  116. for (var i = 0; i < self.length; i++) {
  117. if (fn.call(self[i], i, self[i]) === false) {
  118. return self;
  119. }
  120. }
  121. return self;
  122. },
  123. bind : function(type, fn) {
  124. this.each(function() {
  125. _bind(this, type, fn);
  126. });
  127. return this;
  128. },
  129. unbind : function(type, fn) {
  130. this.each(function() {
  131. _unbind(this, type, fn);
  132. });
  133. return this;
  134. },
  135. fire : function(type) {
  136. if (this.length < 1) {
  137. return this;
  138. }
  139. _fire(this[0], type);
  140. return this;
  141. },
  142. hasAttr : function(key) {
  143. if (this.length < 1) {
  144. return false;
  145. }
  146. return !!_getAttr(this[0], key);
  147. },
  148. attr : function(key, val) {
  149. var self = this;
  150. if (key === undefined) {
  151. return _getAttrList(self.outer());
  152. }
  153. if (typeof key === 'object') {
  154. _each(key, function(k, v) {
  155. self.attr(k, v);
  156. });
  157. return self;
  158. }
  159. if (val === undefined) {
  160. val = self.length < 1 ? null : _getAttr(self[0], key);
  161. return val === null ? '' : val;
  162. }
  163. self.each(function() {
  164. _setAttr(this, key, val);
  165. });
  166. return self;
  167. },
  168. removeAttr : function(key) {
  169. this.each(function() {
  170. _removeAttr(this, key);
  171. });
  172. return this;
  173. },
  174. get : function(i) {
  175. if (this.length < 1) {
  176. return null;
  177. }
  178. return this[i || 0];
  179. },
  180. eq : function(i) {
  181. if (this.length < 1) {
  182. return null;
  183. }
  184. return this[i] ? new KNode(this[i]) : null;
  185. },
  186. hasClass : function(cls) {
  187. if (this.length < 1) {
  188. return false;
  189. }
  190. return _hasClass(this[0], cls);
  191. },
  192. addClass : function(cls) {
  193. this.each(function() {
  194. if (!_hasClass(this, cls)) {
  195. this.className = _trim(this.className + ' ' + cls);
  196. }
  197. });
  198. return this;
  199. },
  200. removeClass : function(cls) {
  201. this.each(function() {
  202. if (_hasClass(this, cls)) {
  203. this.className = _trim(this.className.replace(new RegExp('(^|\\s)' + cls + '(\\s|$)'), ' '));
  204. }
  205. });
  206. return this;
  207. },
  208. html : function(val) {
  209. var self = this;
  210. if (val === undefined) {
  211. if (self.length < 1 || self.type != 1) {
  212. return '';
  213. }
  214. return _formatHtml(self[0].innerHTML);
  215. }
  216. self.each(function() {
  217. _setHtml(this, val);
  218. });
  219. return self;
  220. },
  221. text : function() {
  222. var self = this;
  223. if (self.length < 1) {
  224. return '';
  225. }
  226. return _IE ? self[0].innerText : self[0].textContent;
  227. },
  228. hasVal : function() {
  229. if (this.length < 1) {
  230. return false;
  231. }
  232. return _hasVal(this[0]);
  233. },
  234. val : function(val) {
  235. var self = this;
  236. if (val === undefined) {
  237. if (self.length < 1) {
  238. return '';
  239. }
  240. return self.hasVal() ? self[0].value : self.attr('value');
  241. } else {
  242. self.each(function() {
  243. if (_hasVal(this)) {
  244. this.value = val;
  245. } else {
  246. _setAttr(this, 'value' , val);
  247. }
  248. });
  249. return self;
  250. }
  251. },
  252. css : function(key, val) {
  253. var self = this;
  254. if (key === undefined) {
  255. return _getCssList(self.attr('style'));
  256. }
  257. if (typeof key === 'object') {
  258. _each(key, function(k, v) {
  259. self.css(k, v);
  260. });
  261. return self;
  262. }
  263. if (val === undefined) {
  264. if (self.length < 1) {
  265. return '';
  266. }
  267. return self[0].style[_toCamel(key)] || _computedCss(self[0], key) || '';
  268. }
  269. self.each(function() {
  270. this.style[_toCamel(key)] = val;
  271. });
  272. return self;
  273. },
  274. width : function(val) {
  275. var self = this;
  276. if (val === undefined) {
  277. if (self.length < 1) {
  278. return 0;
  279. }
  280. return self[0].offsetWidth;
  281. }
  282. return self.css('width', _addUnit(val));
  283. },
  284. height : function(val) {
  285. var self = this;
  286. if (val === undefined) {
  287. if (self.length < 1) {
  288. return 0;
  289. }
  290. return self[0].offsetHeight;
  291. }
  292. return self.css('height', _addUnit(val));
  293. },
  294. opacity : function(val) {
  295. this.each(function() {
  296. if (this.style.opacity === undefined) {
  297. this.style.filter = val == 1 ? '' : 'alpha(opacity=' + (val * 100) + ')';
  298. } else {
  299. this.style.opacity = val == 1 ? '' : val;
  300. }
  301. });
  302. return this;
  303. },
  304. data : function(key, val) {
  305. var self = this;
  306. key = 'kindeditor_data_' + key;
  307. if (val === undefined) {
  308. if (self.length < 1) {
  309. return null;
  310. }
  311. return self[0][key];
  312. }
  313. this.each(function() {
  314. this[key] = val;
  315. });
  316. return self;
  317. },
  318. pos : function() {
  319. var self = this, node = self[0], x = 0, y = 0;
  320. if (node) {
  321. if (node.getBoundingClientRect) {
  322. var box = node.getBoundingClientRect(),
  323. pos = _getScrollPos(self.doc);
  324. x = box.left + pos.x;
  325. y = box.top + pos.y;
  326. } else {
  327. while (node) {
  328. x += node.offsetLeft;
  329. y += node.offsetTop;
  330. node = node.offsetParent;
  331. }
  332. }
  333. }
  334. return {x : _round(x), y : _round(y)};
  335. },
  336. clone : function(bool) {
  337. if (this.length < 1) {
  338. return new KNode([]);
  339. }
  340. return new KNode(this[0].cloneNode(bool));
  341. },
  342. append : function(expr) {
  343. this.each(function() {
  344. if (this.appendChild) {
  345. this.appendChild(_get(expr));
  346. }
  347. });
  348. return this;
  349. },
  350. appendTo : function(expr) {
  351. this.each(function() {
  352. _get(expr).appendChild(this);
  353. });
  354. return this;
  355. },
  356. before : function(expr) {
  357. this.each(function() {
  358. this.parentNode.insertBefore(_get(expr), this);
  359. });
  360. return this;
  361. },
  362. after : function(expr) {
  363. this.each(function() {
  364. if (this.nextSibling) {
  365. this.parentNode.insertBefore(_get(expr), this.nextSibling);
  366. } else {
  367. this.parentNode.appendChild(_get(expr));
  368. }
  369. });
  370. return this;
  371. },
  372. replaceWith : function(expr) {
  373. var nodes = [];
  374. this.each(function(i, node) {
  375. _unbind(node);
  376. var newNode = _get(expr);
  377. node.parentNode.replaceChild(newNode, node);
  378. nodes.push(newNode);
  379. });
  380. return K(nodes);
  381. },
  382. empty : function() {
  383. var self = this;
  384. self.each(function(i, node) {
  385. var child = node.firstChild;
  386. while (child) {
  387. if (!node.parentNode) {
  388. return;
  389. }
  390. var next = child.nextSibling;
  391. child.parentNode.removeChild(child);
  392. child = next;
  393. }
  394. });
  395. return self;
  396. },
  397. remove : function(keepChilds) {
  398. var self = this;
  399. self.each(function(i, node) {
  400. if (!node.parentNode) {
  401. return;
  402. }
  403. _unbind(node);
  404. if (keepChilds) {
  405. var child = node.firstChild;
  406. while (child) {
  407. var next = child.nextSibling;
  408. node.parentNode.insertBefore(child, node);
  409. child = next;
  410. }
  411. }
  412. node.parentNode.removeChild(node);
  413. delete self[i];
  414. });
  415. self.length = 0;
  416. return self;
  417. },
  418. show : function(val) {
  419. var self = this;
  420. if (val === undefined) {
  421. val = self._originDisplay || '';
  422. }
  423. if (self.css('display') != 'none') {
  424. return self;
  425. }
  426. return self.css('display', val);
  427. },
  428. hide : function() {
  429. var self = this;
  430. if (self.length < 1) {
  431. return self;
  432. }
  433. self._originDisplay = self[0].style.display;
  434. return self.css('display', 'none');
  435. },
  436. outer : function() {
  437. var self = this;
  438. if (self.length < 1) {
  439. return '';
  440. }
  441. var div = self.doc.createElement('div'), html;
  442. div.appendChild(self[0].cloneNode(true));
  443. html = _formatHtml(div.innerHTML);
  444. div = null;
  445. return html;
  446. },
  447. isSingle : function() {
  448. return !!_SINGLE_TAG_MAP[this.name];
  449. },
  450. isInline : function() {
  451. return !!_INLINE_TAG_MAP[this.name];
  452. },
  453. isBlock : function() {
  454. return !!_BLOCK_TAG_MAP[this.name];
  455. },
  456. isStyle : function() {
  457. return !!_STYLE_TAG_MAP[this.name];
  458. },
  459. isControl : function() {
  460. return !!_CONTROL_TAG_MAP[this.name];
  461. },
  462. contains : function(otherNode) {
  463. if (this.length < 1) {
  464. return false;
  465. }
  466. return _contains(this[0], _get(otherNode));
  467. },
  468. parent : function() {
  469. if (this.length < 1) {
  470. return null;
  471. }
  472. var node = this[0].parentNode;
  473. return node ? new KNode(node) : null;
  474. },
  475. children : function() {
  476. if (this.length < 1) {
  477. return new KNode([]);
  478. }
  479. var list = [], child = this[0].firstChild;
  480. while (child) {
  481. if (child.nodeType != 3 || _trim(child.nodeValue) !== '') {
  482. list.push(child);
  483. }
  484. child = child.nextSibling;
  485. }
  486. return new KNode(list);
  487. },
  488. first : function() {
  489. var list = this.children();
  490. return list.length > 0 ? list.eq(0) : null;
  491. },
  492. last : function() {
  493. var list = this.children();
  494. return list.length > 0 ? list.eq(list.length - 1) : null;
  495. },
  496. index : function() {
  497. if (this.length < 1) {
  498. return -1;
  499. }
  500. var i = -1, sibling = this[0];
  501. while (sibling) {
  502. i++;
  503. sibling = sibling.previousSibling;
  504. }
  505. return i;
  506. },
  507. prev : function() {
  508. if (this.length < 1) {
  509. return null;
  510. }
  511. var node = this[0].previousSibling;
  512. return node ? new KNode(node) : null;
  513. },
  514. next : function() {
  515. if (this.length < 1) {
  516. return null;
  517. }
  518. var node = this[0].nextSibling;
  519. return node ? new KNode(node) : null;
  520. },
  521. scan : function(fn, order) {
  522. if (this.length < 1) {
  523. return;
  524. }
  525. order = (order === undefined) ? true : order;
  526. function walk(node) {
  527. var n = order ? node.firstChild : node.lastChild;
  528. while (n) {
  529. var next = order ? n.nextSibling : n.previousSibling;
  530. if (fn(n) === false) {
  531. return false;
  532. }
  533. if (walk(n) === false) {
  534. return false;
  535. }
  536. n = next;
  537. }
  538. }
  539. walk(this[0]);
  540. return this;
  541. }
  542. });
  543. _each(('blur,focus,focusin,focusout,load,resize,scroll,unload,click,dblclick,' +
  544. 'mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,' +
  545. 'change,select,submit,keydown,keypress,keyup,error,contextmenu').split(','), function(i, type) {
  546. KNode.prototype[type] = function(fn) {
  547. return fn ? this.bind(type, fn) : this.fire(type);
  548. };
  549. });
  550. var _K = K;
  551. K = function(expr, root) {
  552. if (expr === undefined || expr === null) {
  553. return;
  554. }
  555. function newNode(node) {
  556. if (!node[0]) {
  557. node = [];
  558. }
  559. return new KNode(node);
  560. }
  561. if (typeof expr === 'string') {
  562. if (root) {
  563. root = _get(root);
  564. }
  565. var length = expr.length;
  566. if (expr.charAt(0) === '@') {
  567. expr = expr.substr(1);
  568. }
  569. // HTML
  570. // 包含HTML代码,或者第一个字符为"@"时当做HTML字符串
  571. if (expr.length !== length || /<.+>/.test(expr)) {
  572. var doc = root ? root.ownerDocument || root : document,
  573. div = doc.createElement('div'), list = [];
  574. // HTML前添加IMG,防止IE抛出异常
  575. div.innerHTML = '<img id="__kindeditor_temp_tag__" width="0" height="0" style="display:none;" />' + expr;
  576. for (var i = 0, len = div.childNodes.length; i < len; i++) {
  577. var child = div.childNodes[i];
  578. if (child.id == '__kindeditor_temp_tag__') {
  579. continue;
  580. }
  581. list.push(child);
  582. }
  583. return newNode(list);
  584. }
  585. // selector
  586. return newNode(_queryAll(expr, root));
  587. }
  588. // KNode
  589. if (expr && expr.constructor === KNode) {
  590. return expr;
  591. }
  592. // jQuery object
  593. if (expr.toArray) {
  594. expr = expr.toArray();
  595. }
  596. // Native NodeList
  597. if (_isArray(expr)) {
  598. return newNode(expr);
  599. }
  600. // Native Node
  601. return newNode(_toArray(arguments));
  602. };
  603. _each(_K, function(key, val) {
  604. K[key] = val;
  605. });
  606. K.NodeClass = KNode;
  607. window.KindEditor = K;