UNPKG

3.17 kBJavaScriptView Raw
1/**
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18*/
19/* eslint no-useless-escape: 0 */
20
21// contains PLIST utility functions
22var __ = require('underscore');
23var plist = require('plist');
24
25// adds node to doc at selector
26module.exports.graftPLIST = graftPLIST;
27function graftPLIST (doc, xml, selector) {
28 var obj = plist.parse('<plist>' + xml + '</plist>');
29
30 var node = doc[selector];
31 if (node && Array.isArray(node) && Array.isArray(obj)) {
32 node = node.concat(obj);
33 for (var i = 0; i < node.length; i++) {
34 for (var j = i + 1; j < node.length; ++j) {
35 if (nodeEqual(node[i], node[j])) { node.splice(j--, 1); }
36 }
37 }
38 doc[selector] = node;
39 } else {
40 // plist uses objects for <dict>. If we have two dicts we merge them instead of
41 // overriding the old one. See CB-6472
42 if (node && __.isObject(node) && __.isObject(obj) && !__.isDate(node) && !__.isDate(obj)) { // arrays checked above
43 __.extend(obj, node);
44 }
45 doc[selector] = obj;
46 }
47
48 return true;
49}
50
51// removes node from doc at selector
52module.exports.prunePLIST = prunePLIST;
53function prunePLIST (doc, xml, selector) {
54 var obj = plist.parse('<plist>' + xml + '</plist>');
55
56 pruneOBJECT(doc, selector, obj);
57
58 return true;
59}
60
61function pruneOBJECT (doc, selector, fragment) {
62 if (Array.isArray(fragment) && Array.isArray(doc[selector])) {
63 var empty = true;
64 for (var i in fragment) {
65 for (var j in doc[selector]) {
66 empty = pruneOBJECT(doc[selector], j, fragment[i]) && empty;
67 }
68 }
69 if (empty) {
70 delete doc[selector];
71 return true;
72 }
73 } else if (nodeEqual(doc[selector], fragment)) {
74 delete doc[selector];
75 return true;
76 }
77
78 return false;
79}
80
81function nodeEqual (node1, node2) {
82 if (typeof node1 !== typeof node2) { return false; } else if (typeof node1 === 'string') {
83 node2 = escapeRE(node2).replace(/\\\$\S+/gm, '(.*?)');
84 return new RegExp('^' + node2 + '$').test(node1);
85 } else {
86 for (var key in node2) {
87 if (!nodeEqual(node1[key], node2[key])) return false;
88 }
89 return true;
90 }
91}
92
93// escape string for use in regex
94function escapeRE (str) {
95 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
96}